⚡ キャッシュヘッダ解析
URL を入れるだけで Cache-Control・ETag・Expires・Vary・Age を解析し、max-age や s-maxage を読みやすく変換。Cloudflare / CloudFront / Fastly / Akamai / Vercel など主要 CDN を自動検出します。
📚 Cache-Control リファレンス
• public: CDN・プロキシを含む全てのキャッシュで保存可能
• private: ブラウザのみキャッシュ可(共有キャッシュ不可)
• no-store: 一切キャッシュしない
• no-cache: キャッシュしてもよいが、毎回サーバーで再検証する
• max-age=N: N 秒間有効
• s-maxage=N: 共有キャッシュ (CDN) のみに適用される max-age
• immutable: 再検証不要 (リロードでも) — ハッシュ付きアセットに最適
• stale-while-revalidate=N: 期限切れでも N 秒は古い値を返しつつバックグラウンドで再検証
• stale-if-error=N: オリジンエラー時、N 秒は古い値を返してフォールバック
📖 この診断で分かること
この診断は指定した URL のレスポンスヘッダーから Cache-Control・ETag・Last-Modified・Expires と CDN 独自のヘッダーを取り出し、ディレクティブを分解して表示します。判定できるのは「そう指示しているか」までで、実際にキャッシュされたかどうかは分かりません。ブラウザは容量が逼迫すれば指示に関わらず捨てますし、CDN は自社ルールを上書きすることがあります。
| 判定項目 | 何を見ているか | 引っかかったときの対処 |
|---|---|---|
| Cache-Control を書いていない | 指定が無いと「キャッシュされない」のではなく、キャッシュ側が勝手に寿命を推定します(ヒューリスティックキャッシュ)。Last-Modified があると、最終更新からの経過時間の 10% 程度を有効期間とみなす実装が一般的です。1 年前に更新したページなら、およそ 1 か月キャッシュされ得るということです。 |
すべての応答に明示します。HTML は no-cache(保存はするが毎回サーバーに確認する)、内容ハッシュ付きのアセットは max-age=31536000, immutable、個人情報を含む応答は private, no-store の 3 パターンでほぼ足ります。no-cache と no-store は名前が紛らわしいですが、前者は保存する、後者は保存しない、です。 |
| 長い max-age を可変ファイルに付けている | style.css のような固定名のファイルに 1 年の max-age を付けると、更新しても既存の訪問者には 1 年間届きません。しかもブラウザに配ってしまったキャッシュはサーバー側から取り消す手段がありません。CDN のパージが効くのはエッジまでで、利用者の端末には届かないためです。 |
長い TTL は「更新するとファイル名が変わる」設計とセットでのみ使います。app.4f2c1a.css のように内容ハッシュをファイル名に入れ、HTML 側の参照を書き換える形です。この構成なら immutable を付けても安全で、リロードしても再検証すら発生しません。既に長い TTL を配ってしまった場合は、ファイル名を変えて古い方を諦めるのが唯一の回復手段です。 |
| 個人化した応答に public が付いている | ログイン名やカートの中身を含むページに public(あるいは s-maxage)が付くと、共有キャッシュがそれを保存し、次の別の利用者にそのまま配ります。他人の個人情報が表示されるという、キャッシュ設定で起こり得る最悪の事故です。CDN を導入した直後に発覚することが多い問題です。 |
認証後の応答には Cache-Control: private, no-store を返します。Vary: Cookie でも理屈の上では分離できますが、Cookie の値ごとに別エントリになるため実質キャッシュが効かなくなり、CDN の負荷対策としては失敗します。匿名向けと認証済み向けでパスやサブドメインを分け、前者だけをキャッシュ可能にする設計のほうが確実です。 |
キャッシュの怖さは、間違いが自分の手を離れて残り続けるところにあります。設定を直しても、既に配布済みの指示は取り消せません。だからこそ、迷ったら短く始めて後から伸ばすのが鉄則です。stale-while-revalidate を併用すると、期限切れの瞬間に待たせず、古い内容を返しながら裏で更新できるので、短い max-age でも体感速度を落とさずに済みます。CDN を使っているなら、max-age(ブラウザ向け)は短く、s-maxage(CDN 向け)は長く、パージで即時反映という組み合わせが扱いやすい構成です。