nextjs-caching について
キャッシュや ISR の実装・デバッグに取り組む Next.js 開発者向けのガイダンススキルです。キャッシュディレクティブ、再検証 API、レンダリングパターン、よくある注意点を解説します。
主な機能
- 01"use cache" ディレクティブの解説
- 02再検証 API の比較
- 03ISR と部分ページキャッシュの説明
- 04動的ルートとキャッシュ永続性の解説
- 05静的レンダリングの確認とデバッグ
活用シーン
- 01Next.js ページのキャッシュ方式の選択
- 02意図しない動的レンダリングの診断
- 03キャッシュ再検証動作の設計
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ goncy/ skills --skill nextjs-cachingインストール後、Claude Code で/nextjs-cachingを入力して読み込まれたか確認します。
同梱ファイルreferences/detailed-guide.md
詳細
Next.js のキャッシュ
Next.js のキャッシュ機構、ISR パターン、よくある落とし穴に関する専門的なガイダンスです。
基本概念
"use cache" ディレクティブ
コンポーネントや関数をキャッシュ可能としてマークします。このディレクティブはすぐにキャッシュするのではなく、ビルド時に出力をキャッシュするよう指定します。
"use cache"
export default function MyComponent() {
// Output cached at build time
}
ページのメインコンポーネントに適用すると、ページ全体の出力がキャッシュされる(部分的なキャッシュは行われない)ISR に似た動作になります。
自動静的レンダリング
Next.js は動的 API に遭遇するまで上から順にレンダリングし、その時点で「動的な穴」を作成します。ページ全体に ISR の動作を強制する場合を除き、明示的な "use cache" は必要ありません。
キャッシュされた関数は動的とは見なされず、穴も作成しません。
2 段階のレンダリング
- ウォームアップレンダリング(事前評価):動的 API の使用を検出します。マイクロタスク内に解決されないものはすべて動的と見なされます。
- 最終レンダリング:事前レンダリング用に実際の出力を取得します。
再検証 API
revalidateTag と updateTag の比較
revalidateTag:サーバーアクションで使用すると、stale-while-revalidate 方式で再検証します。新しいデータを取得している間、古いコンテンツを提供します。updateTag:自分の書き込みを読み取るパターンで、以前のキャッシュをすぐに削除します。ルートハンドラーでは使用できません。
注:名前に反して、revalidatePath は実際には内部で revalidateTag を使用しています。引数は(ある意味で)パスです。
connection() による置き換え
関数を動的としてマークするには、unstable_noStore() の代わりに connection() を使用します。
ISR パターン
"use cache" を使用した Suspense 境界
"use cache" と Suspense 境界を組み合わせたコンポーネントは、ISR のように動作します。
- 初回リクエストで Suspense 境界がトリガーされる
- コンテンツが表示され、結果がキャッシュされる
- 以降のリクエストではキャッシュされたコンテンツが提供される
Suspense を動的に保つには、静的コンテンツを別のキャッシュ済みコンポーネントに移動します。
境界をまたいでキャッシュ済みの値にアクセスする
コンポーネントだけでなく関数の出力もキャッシュすると、レイアウトとページの間で値を再利用できます。キャッシュ済み関数を再度呼び出して値を取得します。
ページの部分的なキャッシュ
静的コンテンツと動的コンテンツが混在するページの場合:
- ページでは "use cache" を使用しない
- 個々のコンポーネントをキャッシュする
- 動的コンポーネントを Suspense で囲む
- 代替策:並列ルートを使用する
動的ルートと generateStaticParams
重要な要件
静的シェルを生成して ISR の動作を有効にするには、generateStaticParams で少なくとも 1 つのパラメーターをエクスポートします。
export function generateStaticParams() {
return [{ id: 'placeholder' }] // Handle this case in render
}
generateStaticParams がない場合、パラメーターの読み取りより上位に Suspense がないため、動的ページの処理は失敗します。
回避策:サーバーをブロックするために、loading.tsx を追加するか、本文を空の Suspense で囲みます。
キャッシュの永続性
unstable_cache と "use cache: remote" の比較
unstable_cache:デプロイをまたいで保持されます"use cache: remote":デプロイをまたいで保持されません
ビルド時のキャッシュスナップショット
キャッシュ可能な関数は、ビルド時に呼び出された際にスナップショットを作成します。動的コンポーネントで "use cache" を付けた関数を使う場合、キャッシュヒットが保証されるのはビルド時にスナップショットが取得されている場合のみです。それ以外の場合は、メモリー内キャッシュから提供されます。
パフォーマンスとインフラストラクチャ
短時間キャッシュの動作
stale が 30 秒未満のキャッシュは「短時間キャッシュ」となり、実行時のプリフェッチ対象から除外されます。
エッジプロキシの耐障害性
静的シェルを返すプロキシはエッジで実行されます。シェルをすぐに返し、動的コンテンツのリクエスト処理を継続します。あるリージョンで障害が発生しても、プロキシは動作を継続します。
unstable_cache のパフォーマンス
unstable_cache 関数は、レンダリング上は即座に処理されるものと見なされます。
デバッグ
静的ページの確認
ビルドログでは、静的ページに ppr と表示されることがあります。最も確実な確認方法は、ドキュメントリクエストの x-nextjs-cache: HIT ヘッダーを確認することです。
レイアウトで "use cache" を使う際の注意点
ページで "use cache" を設定せず、レイアウトでのみ設定しても、ページは静的になりません。
参考資料
- references/detailed-guide.md:すべてのキャッシュパターンについて、包括的な例と詳細な説明を掲載しています。特定のキャッシュ戦略を実装する場合や、キャッシュの動作をデバッグする場合に参照してください。