Skip to content

Next.js 14 App Router - キャッシング

ソース: https://nextjs.org/docs/14/app/building-your-application/caching

4つのキャッシュメカニズム

メカニズム対象場所目的期間
Request Memoization関数の戻り値サーバーReactコンポーネントツリー内でデータ再利用リクエストライフサイクル
Data Cacheデータサーバーユーザーリクエスト・デプロイを跨いでデータ保存永続的(再検証可能)
Full Route CacheHTML と RSC Payloadサーバーレンダリングコスト削減永続的(再検証可能)
Router CacheRSC Payloadクライアントナビゲーション時のサーバーリクエスト削減セッション or 時間ベース

デフォルトで Next.js は可能な限りキャッシュする。


1. Request Memoization(React の機能)

  • React が fetch を自動メモ化
  • 同じURL・オプションの fetch はレンダリングパス内で1回だけ実行
  • GET メソッドのみ
  • React コンポーネントツリー内のみ(Route Handlers は対象外)
tsx
async function getItem() {
  const res = await fetch('https://.../item/1')
  return res.json()
}

const item = await getItem() // cache MISS(実行される)
const item = await getItem() // cache HIT(メモから返す)

期間: レンダリングパスが完了するまで(サーバーリクエスト単位)

オプトアウト: AbortControllersignal を渡す

js
const { signal } = new AbortController()
fetch(url, { signal })

2. Data Cache

  • fetch の結果をリクエスト・デプロイを跨いで永続的に保存
  • デフォルトでキャッシュ(cache: 'force-cache'

再検証

時間ベース

js
fetch('https://...', { next: { revalidate: 3600 } })  // 1時間

Stale-While-Revalidate 方式:

  1. 期間内のリクエスト → キャッシュデータを返す
  2. 期間後の最初のリクエスト → キャッシュ(stale)を返す + バックグラウンドで再検証
  3. 再検証成功 → キャッシュ更新 / 失敗 → 前のデータを維持

オンデマンド

js
revalidatePath('/')           // パスベース
revalidateTag('collection')   // タグベース
  • オンデマンド再検証はキャッシュエントリを即座に削除
  • 次のリクエストで新しいデータをフェッチ

オプトアウト

js
fetch('https://...', { cache: 'no-store' })

// またはセグメント全体
export const dynamic = 'force-dynamic'

3. Full Route Cache

  • ビルド時に静的レンダリングされたルートのHTML + RSC Payloadをキャッシュ
  • CDNから配信可能

無効化

  1. Data Cache の再検証 → Full Route Cache も無効化
  2. 再デプロイ → Full Route Cache はクリア(Data Cache は永続)

オプトアウト

  • Dynamic Functions の使用(cookies(), headers(), searchParams
  • dynamic = 'force-dynamic' または revalidate = 0
  • Data Cache のオプトアウト(cache: 'no-store' のfetchがあるルート)

4. Router Cache(クライアントサイド)

  • ブラウザのインメモリキャッシュ
  • 訪問済みルートとプリフェッチされたルートのRSC Payloadを保存

期間

  • セッション: ナビゲーション間で持続、ページリフレッシュでクリア
  • 自動無効化期間:
    • 動的レンダリングのルート: 30秒
    • 静的レンダリングのルート: 5分

無効化

  • Server Action で revalidatePath / revalidateTag
  • cookies.set / cookies.delete → 認証変更などに対応
  • router.refresh → Router Cache をクリアし、サーバーに新しいリクエスト

オプトアウト

Router Cache 自体のオプトアウトは不可能<Link prefetch={false}> でプリフェッチは無効化できるが、30秒間はキャッシュされる。


キャッシュの相互作用

Data Cache ↔ Full Route Cache

  • Data Cache の再検証/オプトアウト → Full Route Cache も無効化
  • Full Route Cache のオプトアウト → Data Cache には影響しない

Data Cache ↔ Router Cache

  • Route Handler での Data Cache 再検証 → Router Cache は即座に無効化されない
  • Server Action での再検証 → Router Cache も無効化

API とキャッシュの関係

APIRouter CacheFull Route CacheData CacheReact Cache
<Link prefetch>キャッシュ
router.prefetchキャッシュ
router.refresh再検証
fetchキャッシュキャッシュ
fetch cache:'no-store'オプトアウト
fetch next.revalidate再検証再検証
fetch next.tagsキャッシュキャッシュ
revalidateTag再検証(SA)再検証再検証
revalidatePath再検証(SA)再検証再検証
const revalidate再検証/out再検証/out
const dynamicキャッシュ/outキャッシュ/out
cookies再検証(SA)オプトアウト
headers, searchParamsオプトアウト
generateStaticParamsキャッシュ
React.cacheキャッシュ

SA = Server Action 経由の場合


revalidatePath vs router.refresh

revalidatePathrouter.refresh
Router Cacheクリアクリア
Data Cacheパージ変更なし
Full Route Cacheパージ変更なし
用途サーバーサイドからのデータ・ルート更新クライアントからのUI更新