frontend
S
信頼度ランク
| S | 公式ソース確認済み |
| A | 成功実績多数・失敗例少数 |
| B | 賛否両論 |
| C | 動作未確認・セキュリティリスク高 |
| Z | 個人所感 |
フロントエンド開発者が知るべきHTTPキャッシュの仕組み
Cache-Control・ETag・Last-Modified・Service Workerキャッシュの違いと使い分けを整理。「なぜ古いファイルが表示される?」を解決するHTTPキャッシュの完全ガイド。
一言結論
静的アセットにはハッシュ付きURLとCache-Control: immutableを使い、HTMLにはno-cacheを使うというコンテンツ別の戦略が、「古いファイルが表示される」問題を根本から防ぐ鉄則だ。
キャッシュの種類
ブラウザ → Service Worker → Memory Cache → Disk Cache → CDN → Origin Server
リクエストはこの順に「キャッシュがあるか」を確認します。
Cache-Control ヘッダー
最も重要なヘッダーです。サーバーからブラウザへの指示を伝えます。
Cache-Control: max-age=86400, stale-while-revalidate=3600
主なディレクティブ
| ディレクティブ | 意味 |
|---|---|
max-age=N | N秒間はキャッシュを使う |
no-cache | 毎回サーバーに確認するが、変更なければキャッシュを使う |
no-store | 一切キャッシュしない |
immutable | ファイルは変更されないと宣言(ハッシュ付きファイル向け) |
stale-while-revalidate=N | キャッシュ切れでもN秒間は古いものを返しつつ裏で更新 |
private | ブラウザのみキャッシュ(CDN はキャッシュしない) |
public | CDN を含むすべてでキャッシュ可能 |
ベストプラクティス:コンテンツ別の戦略
静的アセット(JS・CSS・画像)— ハッシュ付きファイル名
Cache-Control: public, max-age=31536000, immutable
ビルドツール(Vite・webpack)が main.a3f5bc.js のようにハッシュをファイル名に埋め込むため、1年間(31536000秒)キャッシュしても安全です。
HTML ファイル — キャッシュしない
Cache-Control: no-cache
HTML は常に最新を確認します。HTML の中でハッシュ付きアセットを参照しているので、HTML が更新されれば新しいアセットが読み込まれます。
API レスポンス
Cache-Control: private, max-age=60 # ユーザー固有データ: 60秒
Cache-Control: public, max-age=3600 # 公開データ: 1時間
Cache-Control: no-store # 個人情報・決済: キャッシュ禁止
ETag と条件付きリクエスト
ETag はファイルの「指紋」です。ブラウザはキャッシュ切れ後、ETag を送ってサーバーに変更を確認します。
# サーバーレスポンス
ETag: "abc123"
# 次回リクエスト(ブラウザが送る)
If-None-Match: "abc123"
# 変更なし → 304 Not Modified(ボディなし、高速)
# 変更あり → 200 OK(新しいボディ)
stale-while-revalidate — UX と鮮度のバランス
Cache-Control: max-age=60, stale-while-revalidate=300
- 0〜60秒: キャッシュを即座に返す
- 60〜360秒: 古いキャッシュを返しつつ、バックグラウンドで更新
- 360秒以降: 必ずサーバーから取得
ユーザーに待ち時間を与えずに新鮮なデータを維持できます。
キャッシュが効かないときのデバッグ
DevTools → Network → リクエストを選択 → Response Headers を確認
よくある原因:
- no-store が設定されている
- max-age=0
- Pragma: no-cache(古い HTTP/1.0 ヘッダー)
- Service Worker が fetch を傍受している
まとめ
| ファイル種別 | 推奨 Cache-Control |
|---|---|
| ハッシュ付き JS・CSS | public, max-age=31536000, immutable |
| HTML | no-cache |
| API(公開) | public, max-age=3600, stale-while-revalidate=86400 |
| API(個人情報) | private, no-store |
キャッシュ設計の鉄則:ハッシュでバスティング + 長期キャッシュが最もパフォーマンスと正確性のバランスが取れた方法です。