MENU

Cache-Control — HTTPキャッシュ挙動を細かく制御するヘッダ

Cache-Control アイキャッチ
Cache-Control

Cache-Controlは、HTTP/1.1で導入されたキャッシュ制御の中心ヘッダで、レスポンスを「どこで」「どれくらい」「どんな条件で」キャッシュ可能かをディレクティブの組み合わせで宣言します。現在の仕様はRFC 9111(2022年、旧RFC 7234)で定義され、max-age=3600(3600秒キャッシュ可)、public(共有キャッシュ可)、private(ブラウザのみ可)、no-cache(毎回検証)、no-store(一切保存禁止)といったディレクティブが代表的です。ブラウザ・CDN・リバースプロキシなど、Webリクエストが通る全ての中継点がこのヘッダを解釈してキャッシュ可否を判断する仕組みで、現代Webパフォーマンスの設計の核となるヘッダです。

目次

この記事の目次

  1. 主要ディレクティブの意味
  2. HTTP/1.0のExpiresからRFC 9111まで
  3. 現場で頻出する設定パターン
  4. Expires・Pragmaとの違い
  5. まとめ

主要ディレクティブの意味

主要ディレクティブの意味

Cache-Controlの中核は「鮮度(freshness)」を表すmax-age=Nディレクティブで、レスポンスをN秒間「新鮮」とみなしてよいことを示します。新鮮な期間内のリクエストはサーバに問い合わせず即座にキャッシュから返され、過ぎた後は「古くなった」状態となり、条件付きリクエスト(If-None-Match等)でサーバに確認してから使うか、再取得するかを選びます。共有キャッシュ(CDNなど)向けに別の鮮度を指定したい場合はs-maxage=Nを併用します。

publicは誰にでも見えてよいリソース(多人数向けの静的ファイルなど)でCDNにキャッシュさせてよいことを示し、privateはブラウザ個別のローカルキャッシュのみに保存可(個人プロフィールページなど)、共有キャッシュには保存させない意思表示です。no-cacheは誤解されやすいですが「キャッシュしない」ではなく「使う前に必ずサーバに検証させる」という意味で、ETagやLast-Modifiedによる条件付きリクエストが毎回行われます。完全に保存させたくない時はno-storeで、ブラウザもCDNもメモリ・ディスクのどちらにも保存しません。これらに加えmust-revalidateimmutablestale-while-revalidateなどの拡張ディレクティブが豊富にあります。

HTTP/1.0のExpiresからRFC 9111まで

HTTP/1.0のExpiresからRFC 9111まで

Webのキャッシュ制御は1996年5月のHTTP/1.0仕様(RFC 1945)から始まりました。当時はExpiresヘッダで「いつまでキャッシュしてよいか」を絶対時刻で指定する単純な仕組みで、サーバとクライアントの時計がずれていると正しく動かない問題がありました。1997年のRFC 2068(HTTP/1.1の最初の仕様)でCache-Controlヘッダが導入され、相対時間(秒単位)と多様なディレクティブで細かい制御が可能になりました。

1999年のRFC 2616でHTTP/1.1の仕様が確定し、Cache-Controlの実装が広く普及しました。2014年のRFC 7234ではキャッシュ部分のみを独立した文書として再編成され、定義の明確化と曖昧さの修正が行われました。2022年6月のRFC 9111でHTTPセマンティクス全体の統合改訂の一環として現代の仕様として確立しました。ChromeやSafariなど主要ブラウザ、Cloudflare・Fastly・AWS CloudFrontなど主要CDNはすべてこの仕様に基づいて動作しており、Web全体の挙動を決定する共通ルールになっています。

現場で頻出する設定パターン

現場で頻出する設定パターン

Webpack・Viteなどのバンドラーで生成されるハッシュ付き静的ファイル(main.a1b2c3.js)にはCache-Control: public, max-age=31536000, immutableを設定するのが定石です。ファイル名にコンテンツハッシュが入っているため変更時は別ファイル名になり、1年間の長期キャッシュとimmutableで「絶対に再検証しない」ことを伝えると、最高効率のキャッシュが効きます。HTML本体は逆に頻繁に変わるため、no-cacheまたはmax-age=0, must-revalidateで毎回検証を要求し、ETagで304返却を狙うパターンが一般的です。

API応答は個人ごとに異なるデータが多いのでCache-Control: private, max-age=60のように短時間ブラウザキャッシュのみ許容する設定が一般的です。認証必要なページや決済関連はCache-Control: private, no-storeで一切保存させない指定も使われます。近年はstale-while-revalidate=N(古くなった後もN秒間は古い値を返しつつ裏で再取得する)を使った体感速度の改善も主流で、Next.jsのISR、Vercel Edge、Cloudflare Workersなど多くのプラットフォームが組み込みでサポートしています。

Expires・Pragmaとの違い

Expires・Pragmaとの違い

ExpiresはHTTP/1.0時代のキャッシュ期限指定ヘッダで、Expires: Thu, 31 Dec 2025 23:59:59 GMTのような絶対時刻を返します。サーバとクライアントの時計がずれていると意図と異なる挙動になる弱点があり、Cache-Control: max-ageの方が相対秒数なので時計ズレに頑健です。Cache-Controlが指定されていればExpiresは無視される優先順位で、現代仕様では実質Cache-Controlが第一選択です。

PragmaヘッダもHTTP/1.0時代の遺物で、Pragma: no-cacheがCache-Control: no-cacheに相当する役割を担っていました。現在では非推奨で、リクエスト側の互換のために残されているだけで、レスポンス側で使う意味はほとんどありません。ETag/Last-Modifiedによる条件付きリクエストはCache-Controlとは別の役割で、こちらは「再検証時の判定基準」を提供し、Cache-Controlは「いつ再検証が必要か」を決定する関係になっています。両者を併用してWebキャッシュの全体設計を組み上げるのが現代の標準的なアプローチです。

まとめ

Cache-ControlはHTTP/1.1で導入されRFC 9111(2022年)で定義されたキャッシュ制御の中核ヘッダです。max-age・public/private・no-cache/no-store・immutable・stale-while-revalidateなど豊富なディレクティブで、ブラウザ・CDN・プロキシの挙動を細かく制御できます。ハッシュ付き静的ファイルにはimmutable、HTML本体にはno-cache、APIにはprivate+短期max-ageといった使い分けで、現代Webパフォーマンス設計の核を担うヘッダです。

※本記事はIT用語辞典の手書きドラフトです。公開前に最新情報・出典を確認のうえ加筆修正してください。

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

この記事を書いた人

コメント

コメントする

目次