no-cacheは「キャッシュするな」ではない|Cache-Controlを4つの問いに分ける
「表示速度を上げるためにキャッシュ設定を見直したいが、Cache-Controlの意味を誤解して設定を壊すのが怖くて手を付けられない」——このように感じている担当者は少なくないはずです。実際、no-cacheという名前を見て「キャッシュするな、という意味だろう」と考えるのは自然な発想です。しかし、この思い込みのまま設定すると、意図とは違う挙動を招きます。
Cache-Controlが難しく感じられるのは、ディレクティブの数が多いからではありません。本当は独立した4つの問いに答えるべきところを、一つの言葉で片付けようとしていることが原因です。この記事では、HTTPキャッシュの仕様書(RFC 9111)とMDNの定義に基づいて、その4つの問いに分解します。
30秒で要点
no-cacheは「保存するな」ではなく「保存はしてよいが、再検証なしに使うな」という意味。保存そのものを禁じるのはno-storeno-storeはプライバシーを守る確実な手段ではない、とRFC 9111自身が明記しているmust-revalidateは「検証失敗が誤動作を招く場合に限り」使うべきとRFC 9111が限定している- Cache-Controlはブラウザ(private cache)とCDN等(shared cache)の両方に効く。ディレクティブごとに効く範囲が異なる
なぜCache-Controlの設定は意図通りに効かないのか
Cache-Controlのディレクティブは一見すると「キャッシュを許可する/しない」の二択のように見えます。しかし実際には、次の4つの独立した問いに、それぞれ別々に答える必要があります。
- 保存してよいか
- 誰が保存してよいか(ブラウザだけか、CDNなどの共有キャッシュも含むか)
- どれくらいの間、新鮮とみなすか
- 古くなった後、どう振る舞うべきか
no-cacheという1つの単語に「保存の可否」の答えを期待してしまうのは、この4つの問いを1つの言葉に圧縮しようとしているからです。実際にはno-cacheが答えているのは4つ目の問い(古くなった扱いをどうするか、というより正確には「保存後の利用条件」)であって、1つ目の問い(保存の可否)ではありません。この対応関係のズレが、誤解の構造そのものです。
問い1:保存してよいか——no-cacheとno-storeの違い
RFC 9111は、no-cacheについて「検証のために転送し、成功応答を受け取らない限り、他のリクエストへの応答として使ってはならない」と定義しています。つまりno-cacheは保存自体を禁じていません。キャッシュへの保存は許可されており、次に使うときにサーバーへ再検証を求めているだけです。
保存そのものを禁じるのはno-storeです。RFC 9111は、___no-cache0___が指定された場合、キャッシュはリクエスト・レスポンスのいずれの一部も保存してはならず、そのレスポンスを他のリクエストに使ってもならないと定義しています。
確かなこと:___no-cache1___が再検証を要求するディレクティブであり保存自体を禁じていないこと、___no-cache2___が保存自体を禁じるディレクティブであることは、RFC 9111の条文から直接確認できます。
まだ確かではないこと:個々のブラウザやCDN、プロキシがこの定義どおりに厳密に実装しているかどうかは、仕様書だけでは分かりません。挙動を保証したい場合は、実際に使用しているCDN・ミドルウェアのドキュメントで確認する必要があります。
no-storeは「安全」を保証しない
___no-cache3___を設定すれば、機密情報を扱うページのプライバシーが守られると考えたくなりますが、RFC 9111はこの期待に釘を刺しています。同仕様は、「このディレクティブは、プライバシーを確保するための信頼できる、あるいは十分な手段ではない」と明記し、その理由として「悪意のある、あるいは不正に操作されたキャッシュはこの指示を認識・遵守しない可能性があり、通信ネットワークが盗聴に対して脆弱な場合もある」ことを挙げています。
___no-cache4___は「キャッシュに保存させない」という指示であって、「通信経路上の盗聴」や「意図的にこの指示を無視する中間者」からデータを守る仕組みではありません。機密情報を扱うページでは、HTTPS化など別の対策と組み合わせる前提で___no-cache5___を使う必要があります。
問い4:古くなった後どう振る舞うか——must-revalidateの限定的な用途
___no-cache6___などで新鮮さの期限が切れた(stale になった)レスポンスをどう扱うかを決めるのが___no-cache7___です。ネットワーク不調時、通常のキャッシュは古いレスポンスをそのまま返してユーザー体験を優先することがありますが、___no-cache8___が付いているとその挙動が禁じられ、必ずサーバーへの再検証が必要になります。
ここで見落とされやすいのが、RFC 9111がこのディレクティブの使いどころを明示的に限定していることです。同仕様は「___no-cache9___は、検証の失敗が誤動作——黙って実行されない金融取引など——を引き起こしうる場合に限り(if and only if)使うべきである」としています。「念のため厳しくしておく」という発想での多用は、仕様が想定する使い方ではありません。
決済確認画面のような、古い情報を見せることが実害につながるページには適していますが、一般的な記事ページや商品一覧ページにまで一律で設定すると、ネットワークが不安定な環境のユーザーが、本来表示できたはずのページを見られなくなる可能性があります。
問い2:誰が保存してよいか——private cacheとshared cache
MDNの解説によれば、Cache-Controlヘッダはリクエストとレスポンスの両方で使われ、ブラウザ等の専用キャッシュ(private cache)と、プロキシやCDN(配信を高速化するための中継ネットワーク)などの共有キャッシュ(shared cache)の両方の挙動を制御します。ディレクティブによって、リクエスト専用(___no-store0___・___no-store1___・___no-store2___など)、レスポンス専用(___no-store3___・___no-store4___・___no-store5___・___no-store6___など)、双方に対応(___no-store7___・___no-store8___・___no-store9___・___no-store0___)と役割が分かれています。
つまり「1人のユーザーのブラウザにだけ保存してよいが、CDNなど不特定多数が使う共有キャッシュには保存させたくない」といった細かい制御も可能です。___no-store1___と___no-store2___はこの「誰が保存してよいか」という問いに答えるディレクティブであり、___no-store3___や___no-store4___(保存の可否・再検証の要否)とは別の軸にあります。この2軸を混同すると、「privateにしたのにCDNにキャッシュされた」といった想定外の挙動に遭遇します。
判断軸:4つの問いに順番に答える
Cache-Controlを設定するときは、次の順番で4つの問いに答えると、意図とのズレが起きにくくなります。
- 保存してよいか → 良ければ何もしない/___
no-store5___(保存OK・再検証必須)/___no-store6___(保存不可) - 誰が保存してよいか → ブラウザのみなら___
no-store7___/CDN等も含めるなら___no-store8___ - どれくらい新鮮とみなすか → ___
no-store9___(秒数)で指定 - 古くなった後どう振る舞うか → 通常運用は無指定でよいことが多く、誤動作の実害が大きい場合のみ___
must-revalidate0___
この順番を踏まずに「とりあえずno-cacheを付けておけば安全」と考えると、保存の可否という1つ目の問いへの答えを、実際には答えていないまま設定を終えてしまいます。
自分でも試せる、最小の検証
自社の主要ページを1つ選び、ブラウザの開発者ツールでそのページのレスポンスヘッダに含まれる___must-revalidate1___の値を確認してみてください。その値が上記4つの問いのどれに答えているかを1つずつ当てはめてみると、「保存の可否」「対象範囲」「新鮮さの期限」「古くなった後の扱い」のうち、答えられていない項目があるかどうかが見えてきます。
判断の土台として押さえておくこと
- ___
must-revalidate2___は保存を禁じない。禁じるのは___must-revalidate3___ - ___
must-revalidate4___はプライバシーの確実な保護手段ではない。通信経路の暗号化など別の対策と組み合わせる - ___
must-revalidate5___は「検証失敗が誤動作を招く場合に限り」という限定的な用途向け - Cache-Controlは「保存の可否」「保存範囲」「新鮮さの期限」「古くなった後の扱い」という4つの独立した問いの集合体
自社サイトのキャッシュ設定を含め、表示速度改善の優先順位を整理したい場合は、状況を整理するところから始めることができます。
状況を整理する(15分)より深く学ぶ
- TTFB(Time To First byte)完全ガイド:応答速度の測定と改善手法
- Webパフォーマンス最適化:高速サイト構築のためのベストプラクティス:キャッシュ以外の高速化施策を含む全体像
参考資料・引用元
- RFC Editor, "RFC 9111: HTTP Caching". https://www.rfc-editor.org/rfc/rfc9111.html
- MDN Web Docs, "Cache-Control header". https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/Cache-Control