😲Nuxt.jsのSSRの挙動に驚いた!
付録:すぐに試せるサンプルアプリ✨
Nuxt.jsのサーバサイドレンダリング (SSR) について調べるため、簡単なアプリを作ってみたら、予想と違う挙動で驚きました。よく考えれば「そうなるだろうな」という話なのですが、さて、ぼくは何に驚いたのでしょうか?
サンプルアプリ
作ったアプリはHerokuで公開しています。
トップページ
トップページでは asyncData
メソッドは使っていません。SSRしたいのは、リンク先のSSRページ (/ssr) です。
SSRページへは、2つの方法でリンクしています。
<nuxt-link>
コンポーネントを使ったリンク<a>
タグを使ったリンク
SSRページ
SSRページでは、asyncData
メソッドを使い、BFF経由でバックエンドAPIを呼び出しています。
「Hello」から始まる太字のテキストは、バックエンドAPIから取得したものです。SEO面で重要なテキストで、したがってSSRが求められているのだと仮定します。
アクセス方法による挙動の違い
🙂直接アクセスした場合
まず、SSRページに直接アクセスした場合の挙動を見てみましょう。ブラウザの開発者ツールで見ると、下記のリクエストが実行されていることが分かります。
/ssr が呼ばれ、/bff は呼ばれていません。ぼくの期待どおり、SSRされていました。これは驚きではありません。
😲<nuxt-link>で遷移した場合
次に、<nuxt-link>
リンクでSSRページに遷移した場合の挙動を見てみます。
/bff が直接よばれています。これがぼくには驚きでした。asyncData
を使ったページは常にSSRされると思い込んでいたのです。
よく考えれば、他のページから遷移する場合は、クライアントサイドでレンダリングするのが妥当です。SEOを気にしなくてよいので、わざわざサーバを呼んでパフォーマンスを落とす必要がありません。納得です。
😲<a>で遷移した場合
最後に、<a>
リンクでSSRページに遷移した場合の挙動を見てみます。
直接アクセスした場合と同じで、SSRされています。これもぼくには驚きでした。<a>
も <nuxt-link>
も大差ない、つまり、<nuxt-link>
はRailsの link_to
のような、<a>
タグ出力用の単純なヘルパーだと思い込んでいたのです。
前述のとおり、<nuxt-link>
を使えばクライアントサイドでの遷移が実現できます。特に理由がなければそうするべきでしょう。
おわりに
サンプルアプリの実装を通じて、Nuxt.jsの下記の挙動が理解できました。
- 同じページでもSSRされたりされなかったりする
- 直接アクセスするとSSRされる
<nuxt-link>
で遷移するとSSRされない<a>
で遷移するとSSRされる
サーバサイドで暮らしてきたぼくには驚きだったのですが、フロントエンドの世界では当然の話なのかもしれません。
アプリのコードはGitHubに置いています。ご興味のある方は遊んでみてください。「Deploy to Heroku」ボタンを付けたので、デプロイも簡単にできます。