キャッシュ戦略
データの取得コストを削減するため、一度取得したデータを再利用する仕組み。何をキャッシュするか、どれくらいの期間キャッシュするか、いつ無効化するかの3点が設計の核心だ。
主要な更新戦略
stale-while-revalidate
ユーザーにはキャッシュされた(古い可能性がある)データを即座に返しつつ、バックグラウンドでデータを更新する戦略。
ユーザーリクエスト
↓
古いキャッシュを返す(即座・高速)
↓(同時に)
バックグラウンドで新しいデータを取得・更新
↓
次のリクエストから新しいデータが返る
レイテンシとデータ鮮度のトレードオフを解決する実践的なアプローチ。HTTP Cache-Controlヘッダーのstale-while-revalidateディレクティブとして標準化されている。
キャッシュの有効期限
| パラメータ | 意味 |
|---|---|
stale / max-age |
この時間内はキャッシュを使い、サーバーに確認しない |
revalidate |
この間隔でバックグラウンド更新を行う |
expire / s-maxage |
キャッシュの最大保持期間 |
キャッシュのデフォルト設計
フレームワークのキャッシュデフォルトは、設計哲学を反映する。
cache by default(オプトアウト型): デフォルトでキャッシュされ、無効化したい場合に明示的に指定する。Next.js 13-14の設計。「賢いデフォルト」として機能するが、意図しないキャッシュ(over-caching)のリスクがある。
cache by consent(オプトイン型): デフォルトでキャッシュされず、有効化したい場合に明示的に宣言する。Next.js 16のuse cacheディレクティブ。何がキャッシュされるかが明確で予測可能だが、開発者の明示的な宣言が必要。
この転換はオプトインとオプトアウトの設計選択であり、明示性と暗黙性のトレードオフでもある。
キャッシュの粒度
- ページ/ルート単位: URLごとにキャッシュ
- コンポーネント単位: 特定のUIコンポーネントの出力をキャッシュ(Next.js 16の
use cache) - 関数/クエリ単位: データ取得関数の結果をキャッシュ
粒度が細かいほど柔軟だが、キャッシュの無効化ロジックが複雑になる。
キャッシュの無効化
「キャッシュの無効化はコンピュータサイエンスで最も難しい問題の一つ」と言われる。主な無効化戦略:
- 時間ベース: TTL(Time To Live)で期限切れにする
- イベントベース: データが更新されたときに明示的に無効化する
- バージョニング: デプロイごとにキャッシュキーを変える(Build IDの利用)
関連
- [[Next.js]] - キャッシュ設計の具体的な実装例
- ISR - Next.jsにおける増分静的再生成(stale-while-revalidateの一形態)
- 明示性と暗黙性 - キャッシュのデフォルト設計の哲学的背景
- オプトインとオプトアウト - cache by default vs cache by consent
- PPR - Next.jsのPartial Prerendering