こんにちは。Naotoです。
Next.jsにおけるページの組み立て方について、AppleのMacBookの商品ページを使って、イメージを整理してみました。
また、文中にキャッシュについての記載がありますが、キャッシュに関する説明は省略しています。
以前にまとめた記事がありますので、こちらをご覧ください。
Server Componentsと Client Componentsの分け方
Server Component(インタラクションが少ない)→ ピンクの部分
- ルート(ページ)単位でStatic Rendering(SSG or ISR) or Dynamic Rendering(SSR)かが決まる。
- 可能な限り、Static Renderingになるようにする。
- 上記画像の場合は、製品ページのため、Static Renderingがベスト。(更新が少ないため)
Dynamic Rendering(SSR)
- 以下のいずれかの条件を満たすページは、Dynamic Renderingになる。
- データフェッチ時にData Cacheを使っていない。(no-store もしくは、revalidateが0。)
- PrismaなどでDBアクセスしているかつ、unstable_cacheを使用していない。
-
cookies()
やheaders()
などのDynamic APIを使用している。 -
pages.tsx
かlayout.tsx
の中に、dynamic = "force-dynamic";
もしくは、revalidate = 0;
を書いている。
- 1と2に当てはまる場合、Streamingを使用すると、データフェッチ完了前に、静的部分+
loading.js
やSuspence
のfallbackUIを先に表示しておき、データフェッチ部分は後から表示できる。(Router Cacheに静的部分+loading.js
やSuspence
のfallbackUIのキャッシュがある場合はより高速に表示できる。)
Static Rendering(SSG or ISR)
- データフェッチがないページはStatic Renderingとなり、Full Route Cacheが使用される。(Data Cacheは使われない。)
- データフェッチ時にData Cacheを使用している場合は、Static Renderingとなり、Data CacheとFull Route Cacheが使用される。
- キャッシュがない(切れている)場合は、初回アクセス時にオリジンサーバにアクセスが行われ、その結果を元にキャッシュが生成され、Data CacheおよびFull Route CacheにSETされる。
PPRの場合(Next.js v15)
- Static RenderingとDynamic Renderingの併用ができる。
- 静的部分+
loading.js
やSuspense
のfallbackUIをStatic RenderingとしてFull Route Cacheを使用して瞬時に表示し、動的(データフェッチ部分)のみDynamic Rendering(SSR)で後から表示できる。
Client Component(インタラクションが多い部分)→ 青の部分
- Client Componentによって形成されている。
- ピンク部分の画面を表示するためのHTML + RSC Payloadと一緒に送られてくるJavaScriptバンドルによってクライアント側で画面が作成される。
- CSRではあるが、初期アクセス時においては、静的部分はあらかじめサーバー側でレンダリングされ、クライアント側ではハイドレーションのみ行われる。
- 初回アクセス時以降の操作時は、クライアント上で再レンダリングされる。(SPAのイメージ)
まとめ
AppleのMacBook商品ページの場合、上記のようなイメージになるのかなと思います。
また、PPRについては、Next.js v15以降の新機能になります。
今までページごとにStatic/Dynamic Renderingを決める必要がありましたが、PPRが登場すれば、コンポーネント単位で、上記を決めることになると思います。
今回の記事は以上です。
最後までお読みいただきありがとうございました!