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 Cache | HTMLとRSCペイロード | サーバー | レンダリングコストを削減し、パフォーマンスを向上させる | 永続的(再検証可能) |
Router Cache | RSCペイロード | クライアント | ナビゲーション時のサーバーリクエストを削減する | ユーザーセッションまたは時間ベース |
デフォルトでは、Next.jsはパフォーマンスを向上させ、コストを削減するために可能な限りキャッシュします。これは、ルートが静的にレンダリングされ、データリクエストがキャッシュされることを意味しますが、オプトアウトすることもできます。以下の図は、ビルド時にルートが静的にレンダリングされ、静的ルートが最初に訪問されたときのデフォルトのキャッシュ動作を示しています。
キャッシュ動作は、ルートが静的または動的にレンダリングされるか、データがキャッシュされているか、リクエストが初回訪問の一部か、後続のナビゲーションの一部かによって変わります。使用ケースに応じて、個々のルートやデータリクエストのキャッシュ動作を設定できます。
Request Memoization
Next.jsは、同じURLとオプションを持つリクエストを自動的にメモ化するようにfetch
APIを拡張しています。これにより、Reactコンポーネントツリーの複数の場所で同じデータのfetch関数を呼び出しても、実行は1回だけですみます。
たとえば、ルート全体で同じデータを使用する必要がある場合(例:Layout、Page、および複数のコンポーネントで)、ツリーのトップでデータを取得し、コンポーネント間でpropsを転送する必要はありません。代わりに、必要なコンポーネントでデータを取得し、同じデータに対してネットワーク上で複数のリクエストを行うことによるパフォーマンスへの影響を心配することなく使用できます。
- TypeScript
- JavaScript
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
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の仕組み
- ルートをレンダリングする際、特定のリクエストが初めて呼び出されたとき、その結果はメモリに存在せず、キャッシュ
MISS
となります; - したがって、関数が実行され、外部ソースからデータが取得され、結果がメモリに保存されます;
- 同じレンダリングパス内でのリクエストの後続の関数呼び出しはキャッシュ
HIT
となり、関数を実行せずにメモリからデータが返されます; - ルートがレンダリングされ、レンダリングパスが完了すると、メモリが「リセット」され、すべてのリクエストメモ化エントリがクリアされます;
Good to know:
- Request MemoizationはReactの機能であり、Next.jsの機能ではありません。他のキャッシュメカニズムとの相互作用を示すためにここに含まれています;
- メモ化は
fetch
リクエストのGET
メソッドにのみ適用されます;- メモ化はReact Component treeにのみ適用されます。つまり:
generateMetadata
、generateStaticParams
、Layouts、Pages、およびその他のServer Componentsでのfetch
リクエストに適用されます;- Route Handlersでの
fetch
リクエストには適用されません。これらはReact component treeの一部ではないためです;fetch
が適していない場合(例:一部のデータベースクライアント、CMSクライアント、GraphQLクライアント)、Reactcache
関数を使用して関数をメモ化できます;
期間
キャッシュはサーバーリクエストのライフタイムが終了し、React component treeのレンダリングが完了するまで持続します。
再検証
メモ化はサーバーリクエスト間で共有されず、レンダリング中にのみ適用されるため、再検証する必要はありません。
オプトアウト
メモ化はfetch
リクエストのGET
メソッドにのみ適用され、POST
やDELETE
などの他のメソッドはメモ化されません。このデフォルトの動作はReactの最適化であり、オプトアウトすることはお勧めしません。
個々のリクエストを管理するには、AbortController
のsignal
プロパティを使用できます。ただし、これによりリクエストがメモ化からオプトアウトするのではなく、進行中のリクエストを中止します。
const { signal } = new AbortController()
fetch(url, { signal })
Data Cache
Next.jsには、サーバーリクエストとデプロイメント間でデータフェッチの結果を永続化する組み込みのData Cacheがあります。これは、Next.jsがネイティブのfetch
APIを拡張し、サーバー上の各リクエストが独自の永続的なキャッシュセマンティクスを設定できるようにすることで可能になります。
Good to know: ブラウザでは、
fetch
のcache
オプションはリクエストがブラウザのHTTPキャッシュとどのように相互作用するかを示しますが、Next.jsでは、cache
オプションはサーバー側のリクエストがサーバーのData Cacheとどのように相互作用するかを示します。
fetch
のcache
およびnext.revalidate
オプションを使用して、キャッシュ動作を設定できます。
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からのコンテンツが更新されたときに、できるだけ早く最新のデータを表示したい場合に役立ちます;
時間ベースの再検証
一定の間隔でデータを再検証するには、fetch
のnext.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
)によってオンデマンドで再検証できます。
オンデマンド再検証の仕組み
fetch
リクエストが初めて呼び出されたとき、データは外部データソースから取得され、Data Cacheに保存されます;- オンデマンド再検証がトリガーされると、適切なキャッシュエントリがキャッシュから削除されます;
- これは、古いデータをキャッシュに保持し、新しいデータが取得されるまで保持する時間ベースの再検証とは異なります;
- 次回リクエストが行われると、再びキャッシュ
MISS
となり、データは外部データソースから取得され、Data Cacheに保存されます;
オプトアウト
fetch
からのレスポンスをキャッシュしたくない場合は、次のようにします:
let data = await fetch('https://api.vercel.app/blog', { cache: 'no-store' })
Full Route Cache
関連用語:
Automatic Static Optimization、Static Site Generation、またはStatic Renderingという用語が、アプリケーションのルートをビルド時にレンダリングおよびキャッシュするプロセスを指すために互換的に使用されることがあります。
Next.jsは、ビルド時にルートを自動的にレンダリングし、キャッシュします。これは、キャッシュされたルートを提供することで、サーバーでのレンダリングを毎回行う代わりに、より高速なページロードを実現する最適化です。
Full Route Cacheの仕組みを理解するには、Reactがレンダリングをどのように処理し、Next.jsがその結果をどのようにキャッシュするかを見てみると役立ちます:
1. サーバーでのReactレンダリング
サーバー上で、Next.jsはReactのAPIを使用してレンダリングを調整します。レンダリング作業は、個々のルートセグメントとSuspense境界によってチャンクに分割されます。
各チャンクは2つのステップでレンダリングされます:
- ReactはServer Componentsをストリーミングに最適化された特別なデータ形式であるReact Server Component Payloadにレンダリングします;
- 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)
Next.jsのデフォルトの動作は、ルートのレンダリング結果(React Server Component PayloadとHTML)をサーバー上でキャッシュすることです。これは、ビルド時または再検証中に静的にレンダリングされたルートに適用されます。
3. クライアントでのReactハイドレーションと調整
リクエスト時に、クライアント上で:
- HTMLは、ClientとServer Componentsのインタラクティブでない初期プレビューを即座に表示するために使用されます;
- React Server Components Payloadは、ClientとレンダリングされたServer Component treeを調整し、DOMを更新するために使用されます;
- 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を無効化する方法は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 Actionで
revalidatePath
またはrevalidateTag
を使用できます; - Route HandlerでData Cacheを再検証しても、Router Cacheは即座に無効化されません。Route Handlerは特定のルートに結び付けられていないためです。したがって、Router Cacheはハードリフレッシュが行われるか、自動無効化期間が経過するまで、以前のペイロードを提供し続けます;
API
次の表は、さまざまなNext.js APIがキャッシュにどのように影響するかの概要を示しています:
API | Router Cache | Full Route Cache | Data Cache | React Cache |
---|---|---|---|---|
<Link prefetch> | Cache | |||
router.prefetch | Cache | |||
router.refresh | Revalidate | |||
fetch | Cache | Cache | ||
fetch options.cache | CacheまたはOpt out | |||
fetch options.next.revalidate | Revalidate | Revalidate | ||
fetch options.next.tags | Cache | Cache | ||
revalidateTag | Revalidate (Server Action) | Revalidate | Revalidate | |
revalidatePath | Revalidate (Server Action) | Revalidate | Revalidate | |
const revalidate | RevalidateまたはOpt out | RevalidateまたはOpt out | ||
const dynamic | CacheまたはOpt out | CacheまたはOpt out | ||
cookies | Revalidate (Server Action) | Opt out | ||
headers , searchParams | Opt out | |||
generateStaticParams | Cache | |||
React.cache | Cache | |||
unstable_cache | Cache |
<Link>
デフォルトでは、<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
fetch
のnext.revalidate
オプションを使用して、個々のfetch
リクエストの再検証期間(秒単位)を設定できます。これにより、Data Cacheが再検証され、Full Route Cacheも再検証されます。新しいデータが取得され、コンポーネントがサーバー上で再レンダリングされます。
// 最大1時間後に再検証
fetch(`https://...`, { next: { revalidate: 3600 } })
fetch
APIリファレンスで詳細なオプションを確認してください。
fetch options.next.tags
とrevalidateTag
Next.jsには、細かいデータキャッシングと再検証のためのキャッシュタグシステムがあります。
fetch
またはunstable_cache
を使用する際に、キャッシュエントリに1つ以上のタグを設定するオプションがあります;- 次に、
revalidateTag
を呼び出して、そのタグに関連付けられたキャッシュエントリを削除できます;
たとえば、データを取得する際にタグを設定できます:
// タグ付きでデータをキャッシュ
fetch(`https://...`, { next: { tags: ['a', 'b', 'c'] } })
次に、特定のタグでrevalidateTag
を呼び出してキャッシュエントリを削除します:
// 特定のタグを持つエントリを再検証
revalidateTag('a')
達成しようとしていることに応じて、revalidateTag
を使用できる場所は2つあります:
- Route Handlers - サードパーティのイベント(例:Webhook)に応じてデータを再検証するため。これにより、Router Cacheは即座に無効化されません。Router Handlerは特定のルートに結び付けられていないためです;
- Server Actions - ユーザーアクション(例:フォーム送信)後にデータを再検証するため。これにより、関連するルートのRouter Cacheが無効化されます;
revalidatePath
revalidatePath
を使用すると、データを手動で再検証し、特定のパス以下のルートセグメントを単一の操作で再レンダリングできます。revalidatePath
メソッドを呼び出すと、Data Cacheが再検証され、Full Route Cacheが無効化されます。
revalidatePath('/')
達成しようとしていることに応じて、revalidatePath
を使用できる場所は2つあります:
- Route Handlers - サードパーティのイベント(例:Webhook)に応じてデータを再検証するため;
- 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
cookies
やheaders
のような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
にパスの完全なリストを提供します:
export async function generateStaticParams() {
const posts = await fetch('https://.../posts').then((res) => res.json())
return posts.map((post) => ({
slug: post.slug,
}))
}
ビルド時にパスのサブセットを静的にレンダリングし、残りをランタイムで最初に訪問されたときにレンダリングするには、部分的なパスのリストを返します:
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'
を利用します:
export async function generateStaticParams() {
return []
}
Good to know:
generateStaticParams
からは、空であっても配列を返す必要があります。そうしないと、ルートは動的にレンダリングされます。
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クライアントです。
- TypeScript
- JavaScript
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
})
import { cache } from 'react'
import db from '@/lib/db'
export const getItem = cache(async (id) => {
const item = await db.item.findUnique({ id })
return item
})