use cache
use cache
ディレクティブは、コンポーネント、関数、またはファイルをキャッシュ対象として指定します。ファイルの先頭に使用して、ファイル内のすべての関数をキャッシュ可能にしたり、関数の先頭にインラインで使用して関数をキャッシュ可能とマークできます。これは実験的な Next.js 機能であり、use client
や use server
のようなネイティブの React 機能ではありません。
next.config.ts
ファイルで dynamicIO
フラグを使用して、use cache
ディレクティブのサポートを有効にします:
use cache
ディレクティブは、将来的にdynamicIO
フラグとは別に利用可能になります。
キャッシュは、レンダリングやデータリクエストの結果を保存することで、Web アプリケーションのパフォーマンスを向上させる技術です。非同期関数またはリクエスト時のデータに依存する API を使用する際、Next.js は自動的に動的レンダリングに移行します。use cache
ディレクティブを使用することで、これらの操作の結果を明示的にキャッシュし、アプリケーションのレンダリングパフォーマンスを最適化できます。
use cache
ディレクティブは、unstable_cache
関数を置き換えることを目的とした実験的な機能です。JSON データのキャッシュと再検証期間とタグの手動定義に限定される unstable_cache
とは異なり、use cache
はより柔軟性があります。React サーバーコンポーネント(RSC)でシリアライズできるあらゆる種類のデータ、データ取得の出力、コンポーネントの出力を含む、より広範囲のデータをキャッシュできます。
さらに、use cache
は入力と出力の両方を追跡することで、複雑さを自動的に管理し、誤ってキャッシュを汚染する可能性を低減します。入力と出力の両方をシリアライズするため、不正なキャッシュ取得の問題を回避できます。
use cache
ディレクティブ
Next.jsの use cache
ディレクティブにより、ルート全体、コンポーネント、関数の戻り値をキャッシュできます。非同期関数がある場合、ファイルの先頭またはその関数のスコープ内に use cache
を追加することで、キャッシュ可能とマークできます。これにより、戻り値をキャッシュし、後続のレンダリングで再利用できることを Next.js に示します。
補足:
use cache
ディレクティブを使用する関数は、状態の変更、DOM の直接操作、またはインターバルでコードを実行するタイマーの設定などの副作用を持ってはいけません。
再検証
デフォルトでは、use cache
ディレクティブを使用すると、Next.js は 再検証期間を 15 分に設定します。Next.js はほぼ無限の有効期間を設定するため、頻繁に更新する必要のないコンテンツに適しています。
この再検証期間は、あまり変更されないと予想されるコンテンツには有用ですが、cacheLife
および cacheTag
API を使用してキャッシュの動作を設定できます:
これらの API は、クライアントとサーバーのキャッシュレイヤー全体で統合されるため、1 か所でキャッシュのセマンティクスを設定でき、あらゆる場所に適用できます。
基本的な例:
以下の例は、関数レベルで cacheLife
関数を使用して、関数の出力に 1 日の再検証期間を設定する方法を示しています:
キャッシュ再検証の仕組み
15 分の再検証期間が設定されている場合、以下のことが発生します:
- キャッシュ HIT: 15 分以内にリクエストが行われると、キャッシュされたデータが提供され、キャッシュ HIT となります。
- 古いデータ: 15 分経過後にリクエストが行われると、キャッシュされた値は依然として提供されますが、古いものとみなされます。Next.js はバックグラウンドで新しいキャッシュエントリを再計算します。
- キャッシュ MISS: キャッシュエントリの有効期限が切れ、後続のリクエストが行われると、Next.js はこれをキャッシュ MISS として扱い、データが再度計算され、ソースから再取得されます。
cacheLife
による時間ベースの再検証
cacheLife
関数は、use cache
ディレクティブが存在する場所でのみ使用でき、キャッシュプロファイルに基づいて時間ベースの再検証期間を定義できます。
use cache
ディレクティブを使用する際は、キャッシュの動作を明示的に定義するためにキャッシュプロファイルを常に追加することをお勧めします。
キャッシュプロファイルは、以下のプロパティを含むオブジェクトです:
プロパティ | 値 | 説明 | 要件 |
---|---|---|---|
stale | number | クライアントがサーバーに確認せずにキャッシュする値の期間。 | オプション |
revalidate | number | サーバー上でキャッシュを更新する頻度。再検証中は古い値が提供される可能性がある。 | オプション |
expire | number | 値が古いままでいられる最大期間。動的フェッチに切り替わる前に、revalidate より長くなければならない。 | オプション - revalidate より長くする必要あり |
「stale」プロパティは、staleTimes
設定とは異なり、クライアントサイドのルーターキャッシュを特に制御します。staleTimes
は動的および静的データの両方のインスタンスに影響するグローバル設定であるのに対し、cacheLife
設定を使用すると、関数またはルート単位で「stale」時間を定義できます。
補足: 「stale」プロパティは
Cache-control: max-age
ヘッダーを設定しません。代わりに、クライアントサイドのルーターキャッシュを制御します。
デフォルトのキャッシュプロファイル
Next.jsは、さまざまな時間軸でモデル化された名前付きキャッシュプロファイルのセットを提供します。use cache
ディレクティブと共に cacheLife
関数でキャッシュプロファイルを指定しない場合、Next.jsは自動的に「default」キャッシュプロファイルを適用します。
プロファイル | Stale | Revalidate | Expire | 説明 |
---|---|---|---|---|
default | 未定義 | 15 分 | 無限キャッシュ | デフォルトプロファイル。頻繁に更新する必要のないコンテンツに適切 |
seconds | 未定義 | 1 秒 | 1 分 | ほぼリアルタイムの更新を必要とする、急速に変化するコンテンツ用 |
minutes | 5 分 | 1 分 | 1 時間 | 1 時間以内に頻繁に更新されるコンテンツ用 |
hours | 5 分 | 1 時間 | 1 日 | 日次で更新されるが、わずかに古くてもよいコンテンツ用 |
days | 5 分 | 1 日 | 1 週間 | 週次で更新されるが、1 日古くてもよいコンテンツ用 |
weeks | 5 分 | 1 週間 | 1 か月 | 月次で更新されるが、1 週間古くてもよいコンテンツ用 |
max | 5 分 | 1 か月 | 無限キャッシュ | 更新の必要がほとんどない非常に安定したコンテンツ用 |
基本的な例:
キャッシュプロファイルを参照する文字列値には本質的な意味はありません。代わりに、セマンティックなラベルとして機能します。これにより、コードベース内のキャッシュされたコンテンツをより理解し、管理しやすくなります。
再利用可能なキャッシュプロファイルの定義
next.config.ts
ファイルで再利用可能なキャッシュプロファイルを作成できます。ユースケースに適した名前を選択し、stale
、revalidate
、expire
プロパティの値を設定します。必要に応じて、任意の数のカスタムキャッシュプロファイルを作成できます。各プロファイルは、cacheLife
関数に渡される文字列値として参照できます。
上記の例では、14日間キャッシュし、1日ごとに更新をチェックし、14日後にキャッシュを期限切れにします。その後、アプリケーション全体で名前を使用してこのプロファイルを参照できます:
デフォルトのキャッシュプロファイルのオーバーライド
デフォルトのキャッシュプロファイルは、キャッシュ可能な出力のフレッシュさや古さを考える上で便利な方法を提供しますが、アプリケーションのキャッシュ戦略により適合するように名前付きプロファイルを設定することもできます。
デフォルトと同じ名前の新しい設定を作成することで、デフォルトの名前付きキャッシュプロファイルをオーバーライドできます。
以下の例は、デフォルトの「days」キャッシュプロファイルをオーバーライドする方法を示しています:
キャッシュプロファイルのインラインでの定義
特定のユースケースでは、cacheLife
関数にオブジェクトを渡してカスタムキャッシュプロファイルを設定できます:
このインラインキャッシュプロファイルは、作成された関数またはファイルにのみ適用されます。アプリケーション全体で同じプロファイルを再利用する場合は、next.config.ts
ファイルの cacheLife
プロパティに構成を追加できます。
use cache
と cacheLife
の入れ子の使用
同じルートまたはコンポーネントツリー内で複数のキャッシュ動作を定義する場合、内部のキャッシュが独自の cacheLife
プロファイルを指定すると、外部のキャッシュはそれらの中で最も短いキャッシュ期間を尊重します。これは、外部のキャッシュに明示的な cacheLife
プロファイルが定義されていない場合にのみ適用されます。
キャッシュ境界の決定階層:
- Next.jsは、
use cache
境界内で見つかった最も短いキャッシュプロファイルを使用します(内部のuse cache
ディレクティブを除く)。 - キャッシュプロファイルが存在しない場合、すべての内部
use cache
呼び出しの最短プロファイル時間がこのuse cache
に適用されます。内部use cache
がない場合はデフォルトが使用されます。 - 2レベル深い内部キャッシュは、すでに親にその期間を提供しているため、外部キャッシュに影響しません。
例えば、キャッシュプロファイルを指定せずにページに use cache
ディレクティブを追加すると、デフォルトのキャッシュプロファイルが暗黙的に適用されます(cacheLife("default")
)。ページにインポートされたコンポーネントも独自のキャッシュプロファイルを持つ use cache
ディレクティブを使用する場合、外部および内部のキャッシュプロファイルが比較され、プロファイルで設定された最短の期間が適用されます。
別のファイルで、インポートされた子コンポーネントを定義します:
cacheTag
によるオンデマンドの再検証
cacheTag
は、キャッシュデータをオンデマンドで削除するために revalidateTag
と組み合わせて使用されます。cacheTag
関数は、単一の文字列値または文字列の配列を受け取ります。
次の例では、getData
関数が「weeks」キャッシュプロファイルを使用し、関数のキャッシュされた出力に cacheTag
を定義します:
その後、ルートハンドラまたはサーバーアクションなど、別の関数で revalidateTag
APIを使用してオンデマンドでキャッシュを削除できます:
オンデマンドでキャッシュされたデータを削除する詳細については、revalidateTag
のドキュメントを参照してください。
例
use cache
による全ルートのキャッシュ
アプリケーション内の Suspense
境界の配置により、コンポーネントの動的性を決定します。Suspense
境界内のコンポーネントは動的になることが許可されますが、これは自動的に動的になることを意味しません。すべてをキャッシュするか、コンテンツが静的である場合、Next.jsは依然として静的アプリケーションを生成します。Suspense
の使用は、境界内で動的な動作が許可されることを示します。
ルートを静的に保つには、Suspense
境界を避けます。それらを使用する必要がある場合、レイアウトとページコンポーネントの両方に use cache
ディレクティブを追加することで静的ページを維持できます。これらは、アプリケーション内の別のエントリーポイントとして扱われるためです。
これは、以前に export const dynamic = "force-cache"
オプションを使用していたアプリケーションに推奨され、ルート全体が事前レンダリングされることを保証します。
page.tsx
ファイルでは、ファイルの先頭に use cache
ディレクティブを追加し、キャッシュプロファイルを定義できます:
use cache
によるコンポーネント出力のキャッシュ
use cache
をコンポーネントレベルで使用して、そのコンポーネント内で実行されるフェッチや計算をキャッシュできます。アプリケーション全体でコンポーネントを再利用する場合、propsの構造が同じであれば、同じキャッシュエントリーを共有できます。
propsはシリアライズされ、キャッシュキーの一部を形成します。アプリケーション内の複数の場所で同じコンポーネントを使用する場合、シリアライズされたpropsが各インスタンスで同じ値を生成する限り、キャッシュエントリは再利用されます。
use cache
を使用した関数出力のキャッシュ
非同期関数にuse cache
を追加できるため、コンポーネントやルートのみにキャッシュを制限されません。ネットワークリクエスト、データベースクエリ、または非常に遅い計算処理をキャッシュしたい場合があるでしょう。このような作業を含む関数にuse cache
を追加すると、キャッシュ可能になり、再利用時に同じキャッシュエントリを共有します。