HTTP キャッシュ

Cache-Control, ETag, Last-Modified を使った HTTP レベルのキャッシュ制御

HTTPパフォーマンス

HTTP キャッシュとは

HTTP キャッシュは、Cache-ControlETagLast-Modified ヘッダーを使って、ブラウザや CDN にレスポンスをキャッシュさせる仕組みである。同じリソースへの再リクエストを削減し、ページの表示速度を向上させ、サーバーの負荷を軽減する。

Cache-Control ヘッダー

Cache-Control: public, max-age=31536000, immutable
ディレクティブ 意味
public CDN やプロキシでもキャッシュ可能
private ブラウザのみキャッシュ可能 (CDN 不可)
max-age=N N 秒間キャッシュを有効とする
no-cache キャッシュするが、使用前にサーバーに検証する
no-store 一切キャッシュしない
immutable max-age 内は再検証しない
stale-while-revalidate=N 期限切れ後 N 秒間は古いキャッシュを返しつつ裏で更新

コンテンツ種別ごとの設定

コンテンツ Cache-Control 理由
JS/CSS (ハッシュ付き) public, max-age=31536000, immutable ファイル名にハッシュを含むため、内容が変わればURLが変わる
画像 public, max-age=2592000 30日キャッシュ
HTML public, max-age=0, must-revalidate 常にサーバーに検証
API レスポンス no-store キャッシュしない
ユーザー固有データ private, no-store CDN にキャッシュさせない

ETag による条件付きリクエスト

1回目のリクエスト:
  GET /api/users/123200 OK
  → ETag: "abc123"
  → Cache-Control: no-cache

2回目のリクエスト:
  GET /api/users/123
  If-None-Match: "abc123"
  → 304 Not Modified (ボディなし、帯域節約)
  or200 OK + 新しい ETag (データが変更された場合)

ETag はレスポンスのハッシュ値で、データが変更されていなければ 304 を返す。レスポンスボディの転送を省略できる。

CloudFront でのキャッシュ制御

CloudFront はオリジンの Cache-Control ヘッダーに従ってキャッシュする。キャッシュポリシーでオーバーライドも可能。

stale-while-revalidate

Cache-Control: public, max-age=300, stale-while-revalidate=60

300 秒間はキャッシュを返す。300〜360 秒の間は古いキャッシュを即座に返しつつ、バックグラウンドでオリジンから最新データを取得する。ユーザーは常に即座にレスポンスを受け取れる。

よくある失敗

HTML に長い max-age を設定

HTML に max-age=31536000 を設定すると、デプロイしても古い HTML がキャッシュから返り続ける。HTML は max-age=0 にし、JS/CSS はファイル名ハッシュ + 長い max-age にする。

理論と実装の両面から学ぶなら関連書籍が参考になる。

関連用語