メインコンテンツまでスキップ

Next.jsにおけるキャッシュ

Next.jsは、レンダリング作業やデータリクエストをキャッシュすることで、アプリケーションのパフォーマンスを向上させ、コストを削減します。このページでは、Next.jsのキャッシュメカニズム、設定に使用できるAPI、およびそれらがどのように相互作用するかについて詳しく説明します。

Good to know: このページは、Next.jsが内部でどのように動作するかを理解するのに役立ちますが、Next.jsを生産的に使用するために必須の知識ではありません。Next.jsのキャッシュヒューリスティックの多くは、APIの使用方法によって決定され、ゼロまたは最小限の設定で最高のパフォーマンスを発揮するためのデフォルトが設定されています。代わりに例に飛びたい場合は、こちらから始めてください

概要

以下は、さまざまなキャッシュメカニズムとその目的の概要です:

メカニズム内容場所目的期間
Request Memoization関数の戻り値サーバーReact Component treeでデータを再利用するリクエストライフサイクル
Data Cacheデータサーバーユーザーリクエストとデプロイメント間でデータを保存する永続的(再検証可能)
Full Route CacheHTMLとRSCペイロードサーバーレンダリングコストを削減し、パフォーマンスを向上させる永続的(再検証可能)
Router CacheRSCペイロードクライアントナビゲーション時のサーバーリクエストを削減するユーザーセッションまたは時間ベース

デフォルトでは、Next.jsはパフォーマンスを向上させ、コストを削減するために可能な限りキャッシュします。これは、ルートが静的にレンダリングされ、データリクエストがキャッシュされることを意味しますが、オプトアウトすることもできます。以下の図は、ビルド時にルートが静的にレンダリングされ、静的ルートが最初に訪問されたときのデフォルトのキャッシュ動作を示しています。

Next.jsにおける4つのメカニズムのデフォルトのキャッシュ動作を示す図。ビルド時とルートが最初に訪問されたときのHIT、MISS、SET。Next.jsにおける4つのメカニズムのデフォルトのキャッシュ動作を示す図。ビルド時とルートが最初に訪問されたときのHIT、MISS、SET。

キャッシュ動作は、ルートが静的または動的にレンダリングされるか、データがキャッシュされているか、リクエストが初回訪問の一部か、後続のナビゲーションの一部かによって変わります。使用ケースに応じて、個々のルートやデータリクエストのキャッシュ動作を設定できます。

Request Memoization

Next.jsは、同じURLとオプションを持つリクエストを自動的にメモ化するようにfetch APIを拡張しています。これにより、Reactコンポーネントツリーの複数の場所で同じデータのfetch関数を呼び出しても、実行は1回だけですみます。

重複排除されたFetchリクエスト重複排除されたFetchリクエスト

たとえば、ルート全体で同じデータを使用する必要がある場合(例:Layout、Page、および複数のコンポーネントで)、ツリーのトップでデータを取得し、コンポーネント間でpropsを転送する必要はありません。代わりに、必要なコンポーネントでデータを取得し、同じデータに対してネットワーク上で複数のリクエストを行うことによるパフォーマンスへの影響を心配することなく使用できます。

app/example.tsx
async function getItem() {
// `fetch`関数は自動的にメモ化され、結果がキャッシュされます
const res = await fetch('https://.../item/1')
return res.json()
}

// この関数は2回呼び出されますが、最初の1回だけ実行されます
const item = await getItem() // cache MISS

// 2回目の呼び出しはルートのどこにでも配置できます
const item = await getItem() // cache HIT

Request Memoizationの仕組み

Reactレンダリング中のfetchメモ化の仕組みを示す図。Reactレンダリング中のfetchメモ化の仕組みを示す図。
  • ルートをレンダリングする際、特定のリクエストが初めて呼び出されたとき、その結果はメモリに存在せず、キャッシュMISSとなります;
  • したがって、関数が実行され、外部ソースからデータが取得され、結果がメモリに保存されます;
  • 同じレンダリングパス内でのリクエストの後続の関数呼び出しはキャッシュHITとなり、関数を実行せずにメモリからデータが返されます;
  • ルートがレンダリングされ、レンダリングパスが完了すると、メモリが「リセット」され、すべてのリクエストメモ化エントリがクリアされます;

Good to know:

  • Request MemoizationはReactの機能であり、Next.jsの機能ではありません。他のキャッシュメカニズムとの相互作用を示すためにここに含まれています;
  • メモ化はfetchリクエストのGETメソッドにのみ適用されます;
  • メモ化はReact Component treeにのみ適用されます。つまり:
    • generateMetadatagenerateStaticParams、Layouts、Pages、およびその他のServer Componentsでのfetchリクエストに適用されます;
    • Route Handlersでのfetchリクエストには適用されません。これらはReact component treeの一部ではないためです;
  • fetchが適していない場合(例:一部のデータベースクライアント、CMSクライアント、GraphQLクライアント)、React cache関数を使用して関数をメモ化できます;

期間

キャッシュはサーバーリクエストのライフタイムが終了し、React component treeのレンダリングが完了するまで持続します。

再検証

メモ化はサーバーリクエスト間で共有されず、レンダリング中にのみ適用されるため、再検証する必要はありません。

オプトアウト

メモ化はfetchリクエストのGETメソッドにのみ適用され、POSTDELETEなどの他のメソッドはメモ化されません。このデフォルトの動作はReactの最適化であり、オプトアウトすることはお勧めしません。

個々のリクエストを管理するには、AbortControllersignalプロパティを使用できます。ただし、これによりリクエストがメモ化からオプトアウトするのではなく、進行中のリクエストを中止します。

app/example.js
const { signal } = new AbortController()
fetch(url, { signal })

Data Cache

Next.jsには、サーバーリクエストデプロイメント間でデータフェッチの結果を永続化する組み込みのData Cacheがあります。これは、Next.jsがネイティブのfetch APIを拡張し、サーバー上の各リクエストが独自の永続的なキャッシュセマンティクスを設定できるようにすることで可能になります。

Good to know: ブラウザでは、fetchcacheオプションはリクエストがブラウザのHTTPキャッシュとどのように相互作用するかを示しますが、Next.jsでは、cacheオプションはサーバー側のリクエストがサーバーのData Cacheとどのように相互作用するかを示します。

fetchcacheおよびnext.revalidateオプションを使用して、キャッシュ動作を設定できます。

Data Cacheの仕組み

キャッシュされたfetchリクエストとキャッシュされていないfetchリク��エストがData Cacheとどのように相互作用するかを示す図。キャッシュされたリクエストはData Cacheに保存され、メモ化され、キャッシュされていないリクエストはデータソースから取得され、Data Cacheに保存されず、メモ化される。キャッシュされたfetchリクエストとキャッシュされていないfetchリクエストがData Cacheとどのように相互作用するかを示す図。キャッシュされたリクエストはData Cacheに保存され、メモ化され、キャッシュされていないリクエストはデータソースから取得され、Data Cacheに保存されず、メモ化される。
  • レンダリング中に'force-cache'オプションを持つfetchリクエストが初めて呼び出されたとき、Next.jsはData Cacheにキャッシュされたレスポンスがあるかどうかを確認します;
  • キャッシュされたレスポンスが見つかった場合、それは即座に返され、メモ化されます;
  • キャッシュされたレスポンスが見つからない場合、リクエストはデータソースに送信され、結果はData Cacheに保存され、メモ化されます;
  • キャッシュされていないデータ(例:cacheオプションが定義されていない、または{ cache: 'no-store' }を使用している場合)の場合、結果は常にデータソースから取得され、メモ化されます;
  • データがキャッシュされているかキャッシュされていないかに関係なく、リクエストは常にメモ化され、Reactレンダリングパス中に同じデータに対して重複したリクエストを行うことを避けます;

Data CacheとRequest Memoizationの違い

両方のキャッシュメカニズムは、キャッシュされたデータを再利用することでパフォーマンスを向上させるのに役立ちますが、Data Cacheは受信リクエストとデプロイメント間で永続的であるのに対し、メモ化はリクエストのライフタイムのみ持続します。

期間

Data Cacheは、再検証またはオプトアウトしない限り、受信リクエストとデプロイメント間で永続的です。

再検証

キャッシュされたデータは、次の2つの方法で再検証できます:

  • 時間ベースの再検証:一定の時間が経過し、新しいリクエストが行われた後にデータを再検証します。これは、データが頻繁に変更されず、新鮮さがそれほど重要でない場合に役立ちます;
  • オンデマンド再検証:イベントに基づいてデータを再検証します(例:フォーム送信)。オンデマンド再検証は、タグベースまたはパスベースのアプローチを使用して、データのグループを一度に再検証できます。これは、ヘッドレスCMSからのコンテンツが更新されたときに、できるだけ早く最新のデータを表示したい場合に役立ちます;

時間ベースの再検証

一定の間隔でデータを再検証するには、fetchnext.revalidateオプションを使用して、リソースのキャッシュライフタイム(秒単位)を設定できます。

// 最大1時間ごとに再検証
fetch('https://...', { next: { revalidate: 3600 } })

また、Route Segment Configオプションを使用して、セグメント内のすべてのfetchリクエストを設定するか、fetchを使用できない場合に設定することもできます。

時間ベースの再検証の仕組み

時間ベースの再検証の仕組みを示す図。再検証期間後、最初のリクエストで古いデータが返され、その後データが再検証される。時間ベースの再検証の仕組みを示す図。再検証期間後、最初のリクエストで古いデータが返され、その後データが再検証される。
  • revalidateを使用したfetchリクエストが初めて呼び出されたとき、データは外部データソースから取得され、Data Cacheに保存されます;
  • 指定された時間枠内(例:60秒)に呼び出されたリクエストは、キャッシュされたデータを返します;
  • 時間枠が経過した後、次のリクエストはキャッシュされた(現在は古い)データを返します;
    • Next.jsはバックグラウンドでデータの再検証をトリガーします;
    • データが正常に取得されると、Next.jsは新しいデータでData Cacheを更新します;
    • バックグラウンド再検証が失敗した場合、以前のデータは変更されずに保持されます;

これはstale-while-revalidateの動作に似ています。

オンデマンド再検証

データは、パス(revalidatePath)またはキャッシュタグ(revalidateTag)によってオンデマンドで再検証できます。

オンデマンド再検証の仕組み

オンデマンド再検証の仕組みを示す図。再検証リクエスト後にData Cacheが新しいデータで更新される。オンデマンド再検証の仕組みを示す図。再検証リクエスト後にData Cacheが新しいデータで更新される。
  • fetchリクエストが初めて呼び出されたとき、データは外部データソースから取得され、Data Cacheに保存されます;
  • オンデマンド再検証がトリガーされると、適切なキャッシュエントリがキャッシュから削除されます;
    • これは、古いデータをキャッシュに保持し、新しいデータが取得されるまで保持する時間ベースの再検証とは異なります;
  • 次回リクエストが行われると、再びキャッシュMISSとなり、データは外部データソースから取得され、Data Cacheに保存されます;

オプトアウト

fetchからのレスポンスをキャッシュしたくない場合は、次のようにします:

let data = await fetch('https://api.vercel.app/blog', { cache: 'no-store' })

Full Route Cache

関連用語

Automatic Static OptimizationStatic Site Generation、またはStatic Renderingという用語が、アプリケーションのルートをビルド時にレンダリングおよびキャッシュするプロセスを指すために互換的に使用されることがあります。

Next.jsは、ビルド時にルートを自動的にレンダリングし、キャッシュします。これは、キャッシュされたルートを提供することで、サーバーでのレンダリングを毎回行う代わりに、より高速なページロードを実現する最適化です。

Full Route Cacheの仕組みを理解するには、Reactがレンダリングをどのように処理し、Next.jsがその結果をどのようにキャッシュするかを見てみると役立ちます:

1. サーバーでのReactレンダリング

サーバー上で、Next.jsはReactのAPIを使用してレンダリングを調整します。レンダリング作業は、個々のルートセグメントとSuspense境界によってチャンクに分割されます。

各チャンクは2つのステップでレンダリングされます:

  1. ReactはServer Componentsをストリーミングに最適化された特別なデータ形式であるReact Server Component Payloadにレンダリングします;
  2. Next.jsはReact Server Component PayloadとClient ComponentのJavaScript命令を使用して、サーバー上でHTMLをレンダリングします;

これにより、すべてがレンダリングされるのを待たずに作業をキャッシュしたり、レスポンスを送信したりすることができます。代わりに、作業が完了するたびにレスポンスをストリーミングできます。

React Server Component Payloadとは?

React Server Component Payloadは、レンダリングされたReact Server Components treeのコンパクトなバイナリ表現です。クライアント上のReactによってブラウザのDOMを更新するために使用されます。React Server Component Payloadには以下が含まれます:

  • Server Componentsのレンダリング結果
  • Client Componentsがレンダリングされるべき場所のプレースホルダーとそのJavaScriptファイルへの参照
  • Server ComponentからClient Componentに渡されるprops

詳細については、Server Componentsのドキュメントを参照してください。

2. サーバーでのNext.jsキャッシュ(Full Route Cache)

Full Route Cacheのデフォルトの動作を示す図。静的にレンダリングされたルートのためにサーバー上でReact Server Component PayloadとHTMLがキャッシュされる。Full Route Cacheのデフォルトの動作を示す図。静的にレンダリングされたルートのためにサーバー上でReact Server Component PayloadとHTMLがキャッシュされる。

Next.jsのデフォルトの動作は、ルートのレンダリング結果(React Server Component PayloadとHTML)をサーバー上でキャッシュすることです。これは、ビルド時または再検証中に静的にレンダリングされたルートに適用されます。

3. クライアントでのReactハイドレーションと調整

リクエスト時に、クライアント上で:

  1. HTMLは、ClientとServer Componentsのインタラクティブでない初期プレビューを即座に表示するために使用されます;
  2. React Server Components Payloadは、ClientとレンダリングされたServer Component treeを調整し、DOMを更新するために使用されます;
  3. JavaScript命令は、Client Componentsをハイドレートし、アプリケーションをインタラクティブにします;

4. クライアントでのNext.jsキャッシュ(Router Cache)

React Server Component Payloadは、クライアント側のRouter Cacheに保存されます。これは、個々のルートセグメントごとに分割された別のインメモリキャッシュです。このRouter Cacheは、以前に訪問したルートを保存し、将来のルートをプリフェッチすることで、ナビゲーション体験を向上させるために使用されます。

5. 後続のナビゲーション

後続のナビゲーションまたはプリフェッチ中に、Next.jsはReact Server Components PayloadがRouter Cacheに保存されているかどうかを確認します。保存されている場合、新しいリクエストをサーバーに送信することをスキップします。

ルートセグメントがキャッシュにない場合、Next.jsはサーバーからReact Server Components Payloadを取得し、クライアント上のRouter Cacheを更新します。

静的および動的レンダリング

ルートがビルド時にキャッシュされるかどうかは、静的または動的にレンダリングされるかによって異なります。静的ルートはデフォルトでキャッシュされますが、動的ルートはリクエスト時にレンダリングされ、キャッシュされません。

この図は、静的および動的にレンダリングされたルートの違いを、キャッシュされたデータとキャッシュされていないデータで示しています:

静的および動的レンダリングがFull Route Cacheに与える影響。静的ルートはビルド時またはデータ再検証後にキャッシュされ、動的ルートは決してキャッシュされない。静的および動的レンダリングがFull Route Cacheに与える影響。静的ルートはビルド時またはデータ再検証後にキャッシュされ、動的ルートは決してキャッシュされない。

静的および動的レンダリングについて詳しく学びましょう。

期間

デフォルトでは、Full Route Cacheは永続的です。これは、レンダリング出力がユーザーリクエスト間でキャッシュされることを意味します。

無効化

Full Route Cacheを無効化する方法は2つあります:

  • データの再検証:Data Cacheを再検証すると、Router Cacheがサーバー上でコンポーネントを再レンダリングし、新しいレンダリング出力をキャッシュすることで無効化されます;
  • 再デプロイ:Data Cacheとは異なり、Full Route Cacheは新しいデプロイメントでクリアされます;

オプトアウト

Full Route Cacheからオプトアウトする、つまり、すべての受信リクエストに対して動的にコンポーネントをレンダリングするには、次の方法があります:

  • Dynamic APIを使用する:これにより、ルートがFull Route Cacheからオプトアウトされ、リクエスト時に動的にレンダリングされます。Data Cacheは引き続き使用できます;
  • dynamic = 'force-dynamic'またはrevalidate = 0ルートセグメント設定オプションを使用する:これにより、Full Route CacheとData Cacheがスキップされます。つまり、コンポーネントはサーバーへのすべての受信リクエストに対してレンダリングされ、データが取得されます。Router Cacheはクライアント側のキャッシュであるため、引き続き適用されます;
  • Data Cacheからオプトアウトする:キャッシュされていないfetchリクエストを持つルートがある場合、これによりルートがFull Route Cacheからオプトアウトされます。特定のfetchリクエストのデータは、すべての受信リクエストに対して取得されます。キャッシュからオプトアウトしない他のfetchリクエストは、引き続きData Cacheにキャッシュされます。これにより、キャッシュされたデータとキャッシュされていないデータのハイブリッドが可能になります;

クライアント側Router Cache

Next.jsには、ルートセグメントのRSCペイロードをレイアウト、ローディング状態、ページごとに分割して保存するインメモリのクライアント側Router Cacheがあります。

ユーザーがルート間をナビゲートすると、Next.jsは訪問したルートセグメントをキャッシュし、ユーザーがナビゲートする可能性のあるルートをプリフェッチします。これにより、瞬時のバック/フォワードナビゲーション、ナビゲーション間のフルページリロードの回避、React状態とブラウザ状態の保持が実現します。

Router Cacheを使用すると:

  • レイアウトはキャッシュされ、ナビゲーション時に再利用されます(部分レンダリング);
  • ローディング状態はナビゲーション時にキャッシュされ、瞬時のナビゲーションのために再利用されます;
  • ページはデフォルトではキャッシュされませんが、ブラウザのバックワードおよびフォワードナビゲーション中に再利用されます。ページセグメントのキャッシュを有効にするには、実験的なstaleTimes設定オプションを使用できます;

Good to know: このキャッシュは特にNext.jsとServer Componentsに適用され、ブラウザのbfcacheとは異なりますが、同様の結果をもたらします。

期間

キャッシュはブラウザの一時メモリに保存されます。Router Cacheの持続期間を決定する要因は2つあります:

  • セッション:キャッシュはナビゲーション間で持続します。ただし、ページをリフレッシュするとクリアされます;
  • 自動無効化期間:レイアウトとローディング状態のキャッシュは、特定の時間後に自動的に無効化されます。期間は、リソースがどのようにプリフェッチされたか、およびリソースが静的に生成されたかどうかに依存します:
    • デフォルトのプリフェッチprefetch={null}または未指定):動的ページの場合はキャッシュされず、静的ページの場合は5分;
    • フルプリフェッチprefetch={true}またはrouter.prefetch):静的および動的ページの両方で5分;

ページをリフレッシュすると、すべてのキャッシュされたセグメントがクリアされますが、自動無効化期間はプリフェッチされた時点から個々のセグメントにのみ影響します。

Good to know: 実験的なstaleTimes設定オプションを使用して、上記の自動無効化時間を調整できます。

無効化

Router Cacheを無効化する方法は2つあります:

  • Server Action内で:
    • パスでオンデマンドでデータを再検証する(revalidatePath)またはキャッシュタグで(revalidateTag);
    • cookies.setまたはcookies.deleteを使用すると、クッキーを使用するルートが古くならないようにRouter Cacheが無効化されます(例:認証);
  • router.refreshを呼び出すと、Router Cacheが無効化され、現在のルートに対してサーバーへの新しいリクエストが行われます;

オプトアウト

Next.js 15以降、ページセグメントはデフォルトでオプトアウトされています。

Good to know: <Link>コンポーネントのprefetchプロップをfalseに設定することで、プリフェッチからもオプトアウトできます。

キャッシュの相互作用

さまざまなキャッシュメカニズムを設定する際に、それらがどのように相互作用するかを理解することが重要です:

Data CacheとFull Route Cache

  • Data Cacheを再検証またはオプトアウトすると、レンダリング出力がデータに依存しているため、Full Route Cacheが無効化されます;
  • Full Route Cacheを無効化またはオプトアウトしても、Data Cacheには影響しません。キャッシュされたデータとキャッシュされていないデータの両方を持つルートを動的にレンダリングできます。これは、ページのほとんどがキャッシュされたデータを使用しているが、リクエスト時に取得する必要があるデータに依存するコンポーネントがいくつかある場合に役立ちます。すべてのデータを再取得することによるパフォーマンスへの影響を心配することなく、動的にレンダリングできます;

Data Cacheとクライアント側Router Cache

  • Data CacheとRouter Cacheを即座に無効化するには、Server ActionrevalidatePathまたはrevalidateTagを使用できます;
  • Route HandlerでData Cacheを再検証しても、Router Cacheは即座に無効化されません。Route Handlerは特定のルートに結び付けられていないためです。したがって、Router Cacheはハードリフレッシュが行われるか、自動無効化期間が経過するまで、以前のペイロードを提供し続けます;

API

次の表は、さまざまなNext.js APIがキャッシュにどのように影響するかの概要を示しています:

APIRouter CacheFull Route CacheData CacheReact Cache
<Link prefetch>Cache
router.prefetchCache
router.refreshRevalidate
fetchCacheCache
fetch options.cacheCacheまたはOpt out
fetch options.next.revalidateRevalidateRevalidate
fetch options.next.tagsCacheCache
revalidateTagRevalidate (Server Action)RevalidateRevalidate
revalidatePathRevalidate (Server Action)RevalidateRevalidate
const revalidateRevalidateまたはOpt outRevalidateまたはOpt out
const dynamicCacheまたはOpt outCacheまたはOpt out
cookiesRevalidate (Server Action)Opt out
headers, searchParamsOpt out
generateStaticParamsCache
React.cacheCache
unstable_cacheCache

デフォルトでは、<Link>コンポーネントはFull Route Cacheからルートを自動的にプリフェッチし、React Server Component PayloadをRouter Cacheに追加します。

プリフェッチを無効にするには、prefetchプロップをfalseに設定できます。ただし、これによりキャッシュが永久にスキップされるわけではなく、ユーザーがルートを訪問すると、ルートセグメントはクライアント側でキャッシュされます。

<Link>コンポーネントについて詳しく学びましょう。

router.prefetch

useRouterフックのprefetchオプションを使用して、ルートを手動でプリフェッチできます。これにより、React Server Component PayloadがRouter Cacheに追加されます。

useRouterフックのAPIリファレンスを参照してください。

router.refresh

useRouterフックのrefreshオプションを使用して、ルートを手動でリフレッシュできます。これにより、Router Cacheが完全にクリアされ、現在のルートに対してサーバーへの新しいリクエストが行われます。refreshはDataまたはFull Route Cacheには影響しません。

レンダリングされた結果は、React状態とブラウザ状態を保持しながらクライアントで調整されます。

useRouterフックのAPIリファレンスを参照してください。

fetch

fetchから返されるデータは、Data Cacheに自動的にキャッシュされません。

fetchのデフォルトのキャッシュ動作(例:cacheオプションが指定されていない場合)は、cacheオプションをno-storeに設定することと同じです:

let data = await fetch('https://api.vercel.app/blog', { cache: 'no-store' })

fetch APIリファレンスで詳細なオプションを確認してください。

fetch options.cache

個々のfetchをキャッシュにオプトインするには、cacheオプションをforce-cacheに設定します:

// キャッシュにオプトイン
fetch(`https://...`, { cache: 'force-cache' })

fetch APIリファレンスで詳細なオプションを確認してください。

fetch options.next.revalidate

fetchnext.revalidateオプションを使用して、個々のfetchリクエストの再検証期間(秒単位)を設定できます。これにより、Data Cacheが再検証され、Full Route Cacheも再検証されます。新しいデータが取得され、コンポーネントがサーバー上で再レンダリングされます。

// 最大1時間後に再検証
fetch(`https://...`, { next: { revalidate: 3600 } })

fetch APIリファレンスで詳細なオプションを確認してください。

fetch options.next.tagsrevalidateTag

Next.jsには、細かいデータキャッシングと再検証のためのキャッシュタグシステムがあります。

  1. fetchまたはunstable_cacheを使用する際に、キャッシュエントリに1つ以上のタグを設定するオプションがあります;
  2. 次に、revalidateTagを呼び出して、そのタグに関連付けられたキャッシュエントリを削除できます;

たとえば、データを取得する際にタグを設定できます:

// タグ付きでデータをキャッシュ
fetch(`https://...`, { next: { tags: ['a', 'b', 'c'] } })

次に、特定のタグでrevalidateTagを呼び出してキャッシュエントリを削除します:

// 特定のタグを持つエントリを再検証
revalidateTag('a')

達成しようとしていることに応じて、revalidateTagを使用できる場所は2つあります:

  1. Route Handlers - サードパーティのイベント(例:Webhook)に応じてデータを再検証するため。これにより、Router Cacheは即座に無効化されません。Router Handlerは特定のルートに結び付けられていないためです;
  2. Server Actions - ユーザーアクション(例:フォーム送信)後にデータを再検証するため。これにより、関連するルートのRouter Cacheが無効化されます;

revalidatePath

revalidatePathを使用すると、データを手動で再検証し、特定のパス以下のルートセグメントを単一の操作で再レンダリングできます。revalidatePathメソッドを呼び出すと、Data Cacheが再検証され、Full Route Cacheが無効化されます。

revalidatePath('/')

達成しようとしていることに応じて、revalidatePathを使用できる場所は2つあります:

  1. Route Handlers - サードパーティのイベント(例:Webhook)に応じてデータを再検証するため;
  2. Server Actions - ユーザーインタラクション(例:フォーム送信、ボタンのクリック)後にデータを再検証するため;

revalidatePath APIリファレンスで詳細を確認してください。

revalidatePath vs. router.refresh

router.refreshを呼び出すと、Router Cacheがクリアされ、Data CacheまたはFull Route Cacheを無効化せずにサーバー上でルートセグメントが再レンダリングされます;

違いは、revalidatePathがData CacheとFull Route Cacheを削除するのに対し、router.refresh()はData CacheとFull Route Cacheを変更しないことです。これはクライアント側のAPIです;

Dynamic API

cookiesheadersのようなDynamic API、およびPagesのsearchParamsプロップは、ランタイムの受信リクエスト情報に依存します。これらを使用すると、ルートがFull Route Cacheからオプトアウトされ、動的にレンダリングされます。

cookies

Server Actionでcookies.setまたはcookies.deleteを使用すると、クッキーを使用するルートが古くならないようにRouter Cacheが無効化されます(例:認証の変更を反映するため)。

cookies APIリファレンスを参照してください。

Segment Configオプション

Route Segment Configオプションは、ルートセグメントのデフォルトを上書きするか、fetch APIを使用できない場合(例:データベースクライアントやサードパーティライブラリ)に使用できます。

次のRoute Segment Configオプションは、Full Route Cacheからオプトアウトします:

  • const dynamic = 'force-dynamic'

この設定オプションは、すべてのfetchをData Cacheからオプトアウトします(つまり、no-store):

  • const fetchCache = 'default-no-store'

より高度なオプションについては、fetchCacheを参照してください。

Route Segment Configのドキュメントで詳細なオプションを確認してください。

generateStaticParams

動的セグメント(例:app/blog/[slug]/page.js)の場合、generateStaticParamsによって提供されるパスは、ビルド時にFull Route Cacheにキャッシュされます。リクエスト時に、Next.jsはビルド時に知られていなかったパスも最初に訪問されたときにキャッシュします。

ビルド時にすべてのパスを静的にレンダリングするには、generateStaticParamsにパスの完全なリストを提供します:

app/blog/[slug]/page.js
export async function generateStaticParams() {
const posts = await fetch('https://.../posts').then((res) => res.json())

return posts.map((post) => ({
slug: post.slug,
}))
}

ビルド時にパスのサブセットを静的にレンダリングし、残りをランタイムで最初に訪問されたときにレンダリングするには、部分的なパスのリストを返します:

app/blog/[slug]/page.js
export async function generateStaticParams() {
const posts = await fetch('https://.../posts').then((res) => res.json())

// 最初の10件の投稿をビルド時にレンダリング
return posts.slice(0, 10).map((post) => ({
slug: post.slug,
}))
}

すべてのパスを最初に訪問されたときに静的にレンダリングするには、空の配列を返す(ビルド時にパスはレンダリングされません)か、export const dynamic = 'force-static'を利用します:

app/blog/[slug]/page.js
export async function generateStaticParams() {
return []
}

Good to know: generateStaticParamsからは、空であっても配列を返す必要があります。そうしないと、ルートは動的にレンダリングされます。

app/changelog/[slug]/page.js
export const dynamic = 'force-static'

リクエスト時にキャッシュを無効にするには、ルートセグメントにexport const dynamicParams = falseオプションを追加します。この設定オプションが使用されると、generateStaticParamsによって提供されるパスのみが提供され、他のルートは404または一致します(catch-allルートの場合)。

React cache関数

React cache関数を使用すると、関数の戻り値をメモ化し、同じ関数を複数回呼び出しても1回だけ実行されるようにできます。

fetchリクエストは自動的にメモ化されるため、React cacheでラップする必要はありません。ただし、fetch APIが適していない場合のデータリクエストを手動でメモ化するためにcacheを使用できます。たとえば、一部のデータベースクライアント、CMSクライアント、またはGraphQLクライアントです。

utils/get-item.ts
import { cache } from 'react'
import db from '@/lib/db'

export const getItem = cache(async (id: string) => {
const item = await db.item.findUnique({ id })
return item
})