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

Next.jsのキャッシュ

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

知っておくとよいこと: このページは、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

Reactはfetch APIを拡張して、同じURLとオプションを持つリクエストを自動的にメモ化します。これにより、React component tree内の複数の場所で同じデータのfetch関数を呼び出しても、一度だけ実行されます。

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

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

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

// この関数は2回呼ばれますが、最初の1回のみ実行されます
const item = await getItem() // キャッシュ MISS

// 2回目の呼び出しはルートのどこでも行われる可能性があります
const item = await getItem() // キャッシュ HIT

Request Memoizationの仕組み

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

知っておくとよいこと

  • 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を拡張して、サーバー上の各リクエストが独自の永続的なキャッシュセマンティクスを設定できるようにしているためです。

知っておくとよいこと: ブラウザーでは、fetchcacheオプションはリクエストがブラウザーのHTTPキャッシュとどのように対話するかを示しますが、Next.jsでは、cacheオプションはサーバー側リクエストがサーバーのData Cacheとどのように対話するかを示します;

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

Data Cacheの仕組み

Data CacheとキャッシュされていないfetchリクエストがData Cacheとどのように相互作用するかを示す図。キャッシュされたリクエストはData Cacheに保存され、メモ化され、キャッシュされていないリクエストはデータソースから取得され、Data Cacheに保存されず、メモ化されます。Data Cacheとキャッシュされていない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オプションを使用してリソースのキャッシュ期間(秒単位)を設定できます。

// 最高で毎時再検証
fetch('https://...', { next: { revalidate: 3600 } })

あるいは、Route Segment Config optionsを使用して、セグメント内のすべての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は、Layouts、Loading states、Pagesごとに分割されたクライアント側のRouter Cacheに保存されます。このRouter Cacheは、以前に訪問したルートを保存し、将来のルートをプリフェッチすることで、ナビゲーションエクスペリエンスを向上させるために使用されます。

5. Subsequent Navigations

その後のナビゲーションまたはプリフェッチ中、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 stateとブラウザstateが保持されます。

Router Cacheでは:

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

知っておくとよいこと:このキャッシュは特にNext.jsおよびServer Componentsに適用され、ブラウザのbfcacheとは異なりますが、似た結果をもたらします。

期間

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

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

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

知っておくとよいこと: 実験的なstaleTimes設定オプションを使用すると、前述の自動無効化時間を調整できます;

無効化

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

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

オプトアウト

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

知っておくとよいこと<Link>コンポーネントのprefetch propをfalseに設定することで、プリフェッチングをオプトアウトすることもできます;

キャッシュの相互作用

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

データキャッシュとFull Route Cache

  • Data Cacheを再検証またはオプトアウトすると、レンダリング出力がデータに依存しているため、Full Route Cacheが無効化されます;
  • Full Route 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>キャッシュ
router.prefetchキャッシュ
router.refresh再検証
fetchキャッシュキャッシュ
fetch options.cacheキャッシュまたはオプトアウト
fetch options.next.revalidate再検証再検証
fetch options.next.tagsキャッシュキャッシュ
revalidateTag再検証(Server Action)再検証再検証
revalidatePath再検証(Server Action)再検証再検証
const revalidate再検証またはオプトアウト再検証またはオプトアウト
const dynamicキャッシュまたはオプトアウトキャッシュまたはオプトアウト
cookies再検証(Server Action)オプトアウト
headers, searchParamsオプトアウト
generateStaticParamsキャッシュ
React.cacheキャッシュ
unstable_cacheキャッシュ

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

プリフェッチを無効にするには、prefetchプロップをfalseに設定できます; しかし、これはキャッシュを永続的にスキップすることにはならず、ユーザーがルートを訪れたときに引き続きクライアント側でルートセグメントがキャッシュされます;

<Link> コンポーネントについてさらに学んでください;

router.prefetch

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

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

router.refresh

useRouter フックのrefreshオプションを使用してルートを手動で更新できます。これはRouter Cacheを完全にクリアし、現在のルートのためにサーバーに新しいリクエストを行います。 refresh はDataまたはFull Route Cacheに影響を与えません;

レンダリングされた結果は、リアクトステートとブラウザーステートを保持しながらクライアント上で調停されます;

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

fetch

fetchから返されるデータは自動的にData Cacheにキャッシュされます;

fetchからのレスポンスをキャッシュしたくない場合、以下を行うことができます:

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

fetch APIリファレンスで詳細オプションを参照できます;

fetch options.cache

cacheオプションをforce-cacheに設定して個別のfetchをキャッシュにオプトインできます:

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

fetch APIリファレンスを参照して詳細オプションを確認してください;

fetch options.next.revalidate

next.revalidateオプションを使用して、個別のfetchリクエストの再検証期間(秒単位)を設定できます;これによりData Cacheが再検証され、続いてFull Route Cacheが再検証されます;新鮮なデータがフェッチされ、コンポーネントがサーバーで再レンダリングされます;

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

fetch APIリファレンスを参照して詳細オプションを確認してください;

fetch options.next.tagsおよびrevalidateTag

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 Handlerが特定のルートに結びついていないため、Router Cacheを即座に無効にしません;
  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リファレンスを参照してください;

revalidatePathrouter.refresh

router.refreshを呼び出すと、Data CacheやFull Route Cacheを無効にすることなく、Router cacheをクリアし、サーバー上のルートセグメントを再レンダリングします;

revalidatePathはData CacheやFull Route Cacheを削除するのに対して、router.refresh()はData CacheやFull Route Cacheを変更しません;これはクライアントサイドのAPIであるためです;

Dynamic API

cookiesheaders、およびPagesのsearchParamsプロップなどのDynamic APIは、実行時のリクエスト情報に依存します。それらを使用すると、ルートがFull Route Cacheをオプトアウトし、動的にレンダリングされることになります;

cookies

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

cookiesAPIリファレンスを参照してください;

セグメント設定オプション

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

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

  • const dynamic = 'force-dynamic'

この設定オプションは、すべてのフェッチを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 []
}

知っておくとよいことgenerateStaticParamsからは、空であっても配列を返す必要があります。そうしなければ、そのルートは動的にレンダリングされます;

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

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

React cache 関数

React cache 関数を使用すると、関数の戻り値をメモ化し、同じ関数を複数回呼び出すことができますが、一度だけ実行します。

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
})