はじめに
この記事は以下記事の App Router の場合の記事です。
SSG と SSR、プリフェッチについての説明はこの記事では割愛します。
https://qiita.com/mattsu_mocha/items/c84a75ff4c50402c37d8
※ 元々 proxy.ts を入れたら App Router でも挙動が変わる想定で Pages Router の記事は書いていましたが、実際は変わらなかったので記事タイトルは変えています。
前提
この記事は以下の環境での説明になります。
- Next.js(App Router) 16.0.7
- TypeScript
プリフェッチのトリガー条件
App Router でも <Link> のデフォルトはビューポート進入に加えてホバー等でもプリフェッチします。prefetch={false} を指定したときだけ、ビューポート・ホバーのどちらでもプリフェッチされなくなります。
SSG と SSR のプリフェッチ対象
Pages Router と異なり、App Router の場合はプリフェッチされるデータの中心が、ビルド時 JSON から RSC Payload (React Server Component Payload) に置き換わっています。
RSC Payload には、サーバー側で取得・レンダリングされた静的なデータやコンポーネント構造が含まれており、これを先読みすることで、クリック時のハイドレーションが非常に高速になります。
SSG の場合
コード (JSチャンク) と合わせて、ビルド済みでキャッシュされている RSC Payload がプリフェッチされます。クリック時はプリフェッチ済みの RSC が即座に使われるため、待ち時間はほとんど発生しません。
SSR の場合
コード (JSチャンク) に加え、loading.tsx が存在する最も近いルート階層までの RSC ツリーがプリフェッチされます。完全に動的な階層で loading.tsx が無い場合は、過剰なデータ取得を避けるためコードのみが先読みされ、RSC Payload はクリック時に生成されます。
prefetch 属性
prefetch 属性には以下の3つを指定できます。
-
"auto"/null/undefined(デフォルト):SSG はコード+フル RSC、SSR は最寄りのloading.tsxまでの RSC をプリフェッチする -
true:ルート階層全体の RSC データを強制的にプリフェッチし、動的階層でもフルツリーを取得する -
false:ビューポート検知・ホバーの両方でプリフェッチを無効化し、クリック時にのみリソースを取得する
まとめ
- App Router の
<Link>デフォルトはビューポート+hover でプリフェッチし、prefetch={false}の時だけ無効化される - SSG ページはコードとキャッシュ済み RSC Payload、SSR ページは
loading.tsxまでの RSC(なければコードのみ)をプリフェッチする - prefetch 属性の指定値(
"auto"/true/false)で、取得する RSC の範囲やトリガーを細かく制御できる

