HTTPキャッシュを理解すると、「なぜ画面が古いままなのか」「なぜ毎回取り直さなくてよいのか」を説明できるようになります。Cache-Control、ETag、Last-Modified の役割を押さえると、表示速度改善と不具合調査の両方に役立ちます。
HTTPキャッシュは、同じリソースを毎回サーバーから取り直さずに再利用する仕組みです。通信量削減、表示高速化、サーバー負荷軽減に大きく効きます。
Webページやレスポンスは、毎回完全に最新である必要があるものもあれば、少しの間は再利用しても問題ないものもあります。
キャッシュと相性がよいデータ:
慎重に扱う必要があるデータ:
HTTPキャッシュはブラウザだけの話ではありません。ブラウザ、プロキシ、CDNなど複数の場所でキャッシュされる可能性があります。
| 場所 | 役割 | 例 |
|---|---|---|
| ブラウザキャッシュ | ユーザー端末内で再利用する | CSS、画像、APIレスポンス |
| 共有プロキシキャッシュ | 複数ユーザーで共有される | 社内プロキシなど |
| CDNキャッシュ | エッジで配信を高速化する | 静的アセット、公開コンテンツ |
| アプリケーション内部キャッシュ | HTTPの外側で保持する | Redisなど |
HTTP記事としてまず重要なのは、ブラウザキャッシュとCDNキャッシュです。
キャッシュでは「今すぐ再利用してよいか」と「一度サーバーに確認すべきか」を制御します。ここを分けて考えると理解しやすいです。
この判断に使われる主なヘッダー: Cache-Control、Expires、ETag、Last-Modified、If-None-Match、If-Modified-Since
Cache-Control の基本Cache-Control はキャッシュ方針を指定する代表的なヘッダーです。まずはこれを最優先で理解すると、キャッシュ制御の大半が読みやすくなります。
Cache-Control: max-age=3600
これは「このレスポンスは3600秒の間は再利用してよい」という意味です。
代表的なディレクティブ
| 値 | 意味 |
|---|---|
max-age=秒数 | 指定秒数の間は新鮮とみなす |
no-cache | 使う前に再検証が必要 |
no-store | 保存しない |
public | 共有キャッシュでも保存可能 |
private | 個人向けで共有キャッシュには保存させない |
must-revalidate | 期限切れ後は必ず再検証する |
max-agemax-age は最も基本的なキャッシュ時間指定です。静的アセットでは特によく使われます。
Cache-Control: public, max-age=86400
この場合、1日間は再利用されやすくなります。ハッシュ付きCSS、バージョン付きJavaScript、更新頻度の低い画像などに向いています。
no-cacheno-cache は「キャッシュ禁止」ではなく、「使う前にサーバーへ再検証が必要」という意味です。名前で誤解されやすいポイントです。
Cache-Control: no-cache
保存自体はされうるものの、そのまま再利用せず、毎回確認が入るイメージです。
no-storeno-store は保存そのものをさせたくない場合に使います。機密性の高いレスポンスで特に重要です。
Cache-Control: no-store
個人情報を含む画面、決済関連のレスポンス、一時的な認証情報を含む応答に向いています。
public と private| 値 | 意味 |
|---|---|
public | CDNなど共有キャッシュでも利用可能 |
private | ブラウザ向け。共有キャッシュでの保存は避ける |
ログイン中ユーザー専用の画面を public にすると、他のユーザーに個人情報が見える危険があるため、設定には注意が必要です。
ETag と Last-Modifiedキャッシュの有効期限が切れても、内容が変わっていなければ本文を再送しなくてよい場合があります。その再検証に使うのが ETag と Last-Modified です。
ETagETag はレスポンス内容のバージョン識別子のようなものです。クライアントは次回リクエスト時にそれを送り、サーバーは変更の有無を判定できます。
レスポンス例:
HTTP/1.1 200 OK
ETag: "v1-product-list"
Cache-Control: no-cache
Content-Type: application/json
[{"id":1,"name":"Keyboard"}]
次回リクエスト例:
GET /products HTTP/1.1
Host: api.example.com
If-None-Match: "v1-product-list"
サーバー側で内容が変わっていなければ、本文なしで次のように返せます。クライアントは手元のキャッシュを再利用します。
HTTP/1.1 304 Not Modified
ETag: "v1-product-list"
Last-ModifiedLast-Modified はそのリソースが最後に更新された時刻を示します。日時ベースで再検証したいときに使われます。
HTTP/1.1 200 OK
Last-Modified: Tue, 30 Apr 2026 10:00:00 GMT
次回リクエスト例:
GET /news HTTP/1.1
Host: example.com
If-Modified-Since: Tue, 30 Apr 2026 10:00:00 GMT
変更がなければ 304 Not Modified が返ります。
ETag と Last-Modified の比較| 項目 | ETag | Last-Modified |
|---|---|---|
| 判定基準 | 内容の識別子 | 更新時刻 |
| 精度 | 高め | 時刻粒度に依存 |
| 実装 | 少し設計が必要 | 比較的単純 |
| 向いている場面 | APIレスポンス、静的配信 | 更新日時が明確なコンテンツ |
304 Not Modified は何を意味するか304 Not Modified は「変更がないので、すでに持っている内容を使ってよい」というレスポンスです。エラーではありません。
HTTP初学者が誤解しやすいポイントです。304 は失敗ではなく、キャッシュがうまく機能しているサインです。
キャッシュは対象によって設計が変わります。特に静的アセットとAPIレスポンスは、同じ感覚で扱わない方が安全です。
ファイル名にバージョンやハッシュを含められる静的アセットは、強いキャッシュと相性がよいです。
app.abc123.js や styles.9f8e7d.css のように内容が変わればURLも変わるファイルは、長めのキャッシュを設定しやすくなります。
Cache-Control: public, max-age=31536000
APIレスポンスは、利用者ごとの差分や更新頻度を考慮する必要があるため、静的アセットより慎重に設計します。
ETag や max-age を検討private や no-store を検討| 対象 | よくある方針 |
|---|---|
| ハッシュ付きJS/CSS | public, max-age=31536000 |
| 画像 | public, max-age=86400 など |
| 公開API一覧 | public + 短め max-age や ETag |
| ログイン後画面HTML | private, no-cache など |
| 機密情報レスポンス | no-store |
これはあくまで典型例であり、要件次第で変わります。
キャッシュは見えにくいですが、ブラウザの開発者ツールを使うとかなり追えます。レスポンスヘッダーとステータスコードを見るのが基本です。
{{image:devtools_cache_headers}}
確認するとよいポイント: Cache-Control、ETag、Last-Modified、Age、Status Code(200 or 304)
304 Not Modified か 200 OK かを確認する# レスポンスヘッダーを確認する
curl -I https://example.com/app.js
# ETag を使って再検証する
curl -i \
-H 'If-None-Match: "v1-product-list"' \
https://api.example.com/products
# Last-Modified ベースで再検証する
curl -i \
-H 'If-Modified-Since: Tue, 30 Apr 2026 10:00:00 GMT' \
https://example.com/news
| 症状 | 原因になりやすい点 | 確認方法 |
|---|---|---|
| CSSを更新したのに画面が変わらない | ブラウザやCDNが古いファイルを保持 | Cache-Control、URL変更有無を確認する |
| API結果が古い | max-age が長い、再検証不足 | レスポンスヘッダーを確認する |
| 個人情報が共有キャッシュに載る | public 設定ミス | Cache-Control を確認する |
| 毎回フル取得される | キャッシュ方針が弱い、再検証未実装 | ETag、Last-Modified を確認する |
| 304が出て不具合に見える | キャッシュの挙動を誤解している | 304が正常動作であることを確認する |
ETag や短め max-age を使うprivate や no-store を検討するキャッシュは便利ですが、機密情報を誤って残すとセキュリティ事故につながります。特に個人情報や認証関連のレスポンスは慎重に扱う必要があります。
注意したい例:
判断のポイント: 誰向けのレスポンスか、共有キャッシュに載せてよいか、ブラウザ保存自体を避けるべきか、常に最新である必要があるか
HTTPキャッシュは、レスポンスを再利用して性能を高めるための仕組みです。Cache-Control で基本方針を決め、ETag や Last-Modified で再検証を行う、という流れを押さえると実務で使いやすくなります。
Cache-Control はキャッシュ方針の中心max-age、no-cache、no-store、public、private は重要ETag と Last-Modified は再検証に使う304 Not Modified はエラーではなく、未変更を示す正常な応答読み終えたら完了にしましょう
完了ボタンを押すと、モジュール「HTTP入門」の進捗として記録されます。 読んだ内容を振り返るときにも役立ちます。