こんにちはNaotoです。
Next.jsを学ぶ中で、キャッシュについての理解を深めるために、学んだ内容をまとめてみました。
自分用にまとめたものですので、間違っている部分がありましたら、申し訳ありません。
その際は、ご指摘いただければと思います。
インプットは以下です。(ShinCodeさんの動画は本当に最強です。)
では、早速4つのキャッシュについてまとめていきます。(箇条書きすみません。)
1. Request Memoization (サーバー側のキャッシュ)
-
特になにも設定しなくても、Next.jsが自動で行ってくれる、リクエスト結果のキャッシュ。
-
1回のレンダリング期間中にサーバーにて作成/破棄される、ユーザー(デバイス)ごとのキャッシュ。
-
このキャッシュがあることで、同じリクエスト(URLとオプションが一緒の場合)を重複排除できる。
-
ServerComponentで
fetch()
かつGETを使う場合のみ適用される。- ORM等、
fetch()
以外を使う場合は、React Cacheにて対応する必要がある。
- ORM等、
-
データ取得を行う処理は、データ取得層(DAL : Data Access Layer)に分離しておくと良い。(URLの一致が保証されるため。)
2. Data Cache (サーバー側のキャッシュ)
- revalidateしない限り残り続ける、リクエスト結果のキャッシュ。
- 個々の
fetch()
に対するキャッシュであり、JSON形式のレスポンスが、CDN(エッジサーバー)にキャッシュされる。 -
fetch()
の引数でData Cacheの設定ができる。- Static Rendering
-
fetch(”https://…”, {cache: “force-cache”})
- SSG(デフォルトのため省略可)
- Data Cacheにキャッシュされる。永続的に残る。
-
fetch(”https://…”, {cache: {next: {revalidate: 3600}}})
- ISR
- Data Cacheにキャッシュされ、revalidateに設定した期間後にキャッシュが破棄される。
-
- Dynamic Rendering
-
fetch(”https://…”, {cache: “no-store”})
- SSR
- Data Cacheを使用しない。Request MemoizationでHITしない場合、直接Data Source(オリジンサーバー)にアクセスする。(毎回最新のデータが返ってくる。)
-
- Static Rendering
- prismaを使って直接データを取得する場合は、デフォルトでDynamic Rendering(SSR)になっている。
- Static Rendering(SSG or ISR)にしたい場合は、RouteHandlerを介して
fetch()
で呼びだすか、unstable_cache
を使用する。
- Static Rendering(SSG or ISR)にしたい場合は、RouteHandlerを介して
3. Full Route Cache (サーバー側のキャッシュ)
- Static Rendering(SSG, ISR)の時のみ適用されるキャッシュ。
- ページ全体のキャッシュ。
- 静的部分(HTMLやRSC Payload)がキャッシュされる。
4. Router Cache (クライアント側のキャッシュ)
- ナビゲーション用のキャッシュ
- ページを訪問するとRSCペイロードが自動的にキャッシュされる。
- クライアント側でメモリ内にキャッシュされる。
- Linkコンポーネントを使用することでキャッシュが適用される。
- 静的部分では、Linkコンポーネントのプリフェッチ機能(リンクが画面上に現れた際に、あらかじめ静的部分をバックグラウンドにてプリフェッチしてくれる機能)が働く。
- 動的部分はプリフェッチできないため、データ取得時は
loading.js
やSuspence
のfallback UIが表示される。 - キャッシュ期間は、セッション中のみ。
- 静的ページ → デフォルトで5分間。
- 動的ページ →デフォルトで30秒。
- staleTimesでデフォルト時間は変更可能。
キャッシュを無効にする
- Server Actions
-
revalidate Path()
/revalidate Tag()
-
cookies().set()
/cookies().delete()
-
router.refresh
まとめ
上記4つのキャッシュのまとめとして、ユーザーがページにアクセスした際のそれぞれのキャッシュの動きをまとめてみました。
- ユーザがページにアクセス
-
Router Cacheにて、キャッシュの有無を確認
- あり
- キャッシュを利用して、すぐに画面表示 → 処理終了
- なし
- Static Rendering → 3に。
- Dynamic Rendering → 4に。
- あり
-
Full Route Cacheにて、キャッシュの有無を確認
- あり
- キャッシュを利用してすぐに画面表示 + Router CacheにSET → 処理終了
- なし
- Data Cahceにてキャッシュの有無を確認
- あり
- Data Cacheのキャッシュを使用してHTML, RSCペイロードを生成し、Full Route Cache, Router CacheにSETしつつ画面表示 → 処理終了
- なし
- オリジンサーバからデータを取得しData CacheにSETしつつ、HTML, RSCペイロードを生成し、Full Route Cache, Router CacheにもSETしつつ画面表示 → 処理終了
- あり
- Data Cahceにてキャッシュの有無を確認
- あり
-
オリジンサーバにアクセスし、データ取得
- 静的部分+Loading.jsやSuspenceのfallbackUI
- データ取得完了を待たずに、サーバにてレンダリングされ、画面表示
- 動的部分
- 取得完了次第、遅れて画面表示 + 静的部分とともにRouter CacheにSET → 処理終了
- 静的部分+Loading.jsやSuspenceのfallbackUI
※上記の流れの中で、Data Cacheおよびオリジンサーバからデータを取得する際は、Request Memoizationによる重複排除が行われる。
今回の記事は以上です。
最後までお読みいただきありがとうございました!