Next.js Pages Router のレンダリングとプリフェッチに関するクイズ
概要
Next.js Pages Router のレンダリングとプリフェッチの挙動について、クイズを 7 問用意しました。
どれも、私自身が知らなかったり、誤って理解していたポイントに関連した内容です。
対象読者
Next.js を使って開発したことがある人
問題 1
Link コンポーネントには prefetch 機能があります。
prefetch が走るトリガーはなんでしょうか?
解答
Link コンポーネントがビューポートに表示されること。
あるいは、Link コンポーネントをホバーすること。ただし、ビューポートに表示されてからキャッシュの有効期限が切れた場合のみ、ホバーによる prefetch が再度実行されます。
問題 2
getStaticProps でデータフェッチをしているページへの Link コンポーネントが prefetch の条件を満たしたとき、prefetch は走りますか?
prefetch する場合、どのようなデータやファイルが対象でしょうか?
解答
prefetch します。
prefetch されるデータ・ファイル:
- JSON ファイル(getStaticProps の返り値)
- JavaScript バンドル(そのページのコンポーネントのレンダリングに必要な JS ファイル)
ビルド時に生成された JSON ファイル(/_next/data/[buildId]/[pagePath].json)が prefetch されます。
ビルド時に生成された HTML ファイルは prefetch されません。
問題 3
getStaticProps でデータフェッチをしているページへの Link コンポーネントをクリックしたとき、データやファイルの fetch は発生しますか?
発生する場合、どのようなデータやファイルを取得しますか?
ただし、prefetch は完了しているものとします。
解答
fetch しません。
必要なデータはキャッシュ済みのため、追加の fetch は発生しません。
問題 4
getServerSideProps でデータフェッチをしているページへの Link コンポーネントが prefetch の条件を満たしたとき、prefetch は行われますか?
行われる場合、どのようなデータやファイルが対象でしょうか?
解答
prefetch します。
prefetch されるデータ・ファイル:
- JavaScript バンドル
問題 5
getServerSideProps でデータフェッチをしているページへの Link コンポーネントをクリックしたとき、データやファイルの fetch は発生しますか?
発生する場合、どのようなデータやファイルを取得しますか?
ただし、prefetch は完了しているものとします。
解答
fetch します。
fetch されるデータ・ファイル:
- JSON データ(getServerSideProps の返り値)がサーバーから取得される
問題 6
getServerSideProps でデータフェッチをしているページへの Link コンポーネントをクリックした際、サーバーでそのページのコンポーネントはレンダリングされますか?
解答
レンダリングされません。
クライアントサイドナビゲーション(Link コンポーネントによる遷移)の場合:
- サーバーでは getServerSideProps のみが実行される
- サーバーで React コンポーネントのレンダリングは行われない
- JSON データ(getServerSideProps の返り値)のみがクライアントに送信される
サーバーサイドレンダリング(HTML の生成)が行われるのは、初回アクセス時やページリロード時のみです。
問題 7
getStaticProps でデータフェッチをしているページを初回に表示した際、ビルド時に生成した HTML がフロントエンドに返されます。
フロントエンドではそのページのコンポーネントがレンダリングされるでしょうか?
解答
レンダリングされます(ハイドレーションの過程でレンダリングされます)。
初回表示時の流れ:
- サーバーから静的 HTML が返される
- ブラウザが HTML を表示
- JavaScript バンドル(ページコンポーネントのレンダリングに必要な JS ファイル)がロード・実行される
- React がハイドレーションを実行
- ページがインタラクティブになる
まとめ
- Link コンポーネントの prefetch は、ビューポートへの表示とホバーがトリガーになる。
- getStaticProps ページは JSON とバンドルを prefetch し、一度キャッシュされれば遷移時の追加 fetch は不要。
- getServerSideProps ページはバンドルのみを prefetch し、遷移時にサーバーから JSON を受け取る。
- クライアントサイドナビゲーションでは getServerSideProps のみ実行され、サーバー側のコンポーネントレンダリングは発生しない。
- 静的ページでも初回表示後にハイドレーションが走り、フロントエンドでコンポーネントがレンダリングされる。
Discussion