#はじめに
「同じ画像を何度もダウンロードするのは無駄では?」——その通りです。HTTPキャッシュは、この無駄を省くための仕組みです。
適切にキャッシュを設定すれば、ページの読み込みが高速化し、サーバーの負荷も軽減できます。しかし、設定を誤ると「更新したのに古い内容が表示される」という問題に悩まされます。
この記事を読むと、以下のことができるようになります:
- HTTPキャッシュの基本的な仕組みを理解できる
- ブラウザがキャッシュを使うかどうかの判断基準がわかる
- DevToolsでキャッシュの状態を確認できる
#なぜキャッシュが必要か
Webページを開くたびに、多くのリソースをダウンロードします。
index.html → 10KB
style.css → 50KB
app.js → 200KB
logo.png → 30KB
hero.jpg → 500KB
合計: 約800KB
毎回すべてをダウンロードすると:
- ユーザー: ページ表示が遅い
- サーバー: 負荷が高い
- 通信: 帯域を無駄に消費
キャッシュがあれば、変更のないリソースはローカルから読み込めます。
#キャッシュの種類
#ブラウザキャッシュ(プライベートキャッシュ)
各ユーザーのブラウザに保存されるキャッシュです。
[ブラウザ] ←→ [ブラウザキャッシュ] ←→ [サーバー]
特徴:
- ユーザーごとに独立
- ユーザー固有のデータもキャッシュ可能
- ブラウザのディスクに保存
#共有キャッシュ
複数のユーザー間で共有されるキャッシュです(CDN、プロキシなど)。
[ブラウザA] ←┐
├→ [CDNキャッシュ] ←→ [サーバー]
[ブラウザB] ←┘
特徴:
- 複数ユーザーで共有
- ユーザー固有のデータはキャッシュ不可
- サーバーへのリクエストを大幅に削減
#キャッシュの基本フロー
#1. 初回リクエスト
[ブラウザ] [サーバー]
| |
|------ GET /style.css ------------->|
| |
|<----- 200 OK ----------------------|
| Cache-Control: max-age=3600 |
| [CSSの内容] |
| |
↓ ブラウザがキャッシュに保存
#2. 2回目のリクエスト(キャッシュ有効期間内)
[ブラウザ] [キャッシュ]
| |
|------ GET /style.css →|
| |
| キャッシュから返す |
| (サーバーへのリクエストなし)
| |
|<----- 200 OK ---------|
サーバーへのリクエストは発生せず、キャッシュから即座に返されます。
#3. キャッシュ有効期限切れ後
有効期限が切れると、サーバーに再度リクエストします。このとき「条件付きリクエスト」を使って、リソースが変更されているかを確認できます(後の記事で詳しく学びます)。
#Cache-Controlヘッダー
キャッシュの動作を制御する最も重要なヘッダーです。
#レスポンスでの使用
サーバーがクライアントにキャッシュ方法を指示します。
Cache-Control: max-age=3600
#リクエストでの使用
クライアントがキャッシュの使用方法を指定します。
Cache-Control: no-cache
#基本的なディレクティブ
| ディレクティブ | 意味 |
|---|---|
max-age=N | N秒間キャッシュを有効とする |
no-cache | キャッシュ前にサーバーで検証必須 |
no-store | キャッシュを一切禁止 |
public | 共有キャッシュでもキャッシュ可能 |
private | ブラウザキャッシュのみ可能 |
#freshとstale
キャッシュされたリソースは、2つの状態を持ちます。
#fresh(新鮮)
有効期限内のキャッシュ。サーバーへの確認なしに使用できます。
max-age=3600 で取得
現在: 取得から30分後
→ fresh(残り30分有効)
#stale(古い)
有効期限が切れたキャッシュ。使用前にサーバーへの確認が必要です。
max-age=3600 で取得
現在: 取得から2時間後
→ stale(期限切れ)
staleなキャッシュは即座に破棄されるわけではなく、条件付きリクエストで再検証できます。
#DevToolsでキャッシュを確認
#Networkタブでの確認
- DevToolsを開く
- Networkタブを選択
- リクエストを確認
確認ポイント:
| 列 | 意味 |
|---|---|
| Status | 200 (from disk cache) = ディスクキャッシュから |
200 (from memory cache) = メモリキャッシュから | |
304 Not Modified = 条件付きリクエストでキャッシュ使用 | |
| Size | (disk cache) または (memory cache) と表示 |
#キャッシュの無効化
開発中はキャッシュを無効化したいことがあります。
- Networkタブを開く
- 「Disable cache」にチェック
- DevToolsを開いている間、キャッシュが無効に
または、ハードリロード:
- Mac:
Cmd + Shift + R - Windows:
Ctrl + Shift + R
#レスポンスヘッダーの確認
- リクエストをクリック
- Headersタブを選択
- Response Headersセクションで
Cache-Controlを確認
#キャッシュの判断フロー
ブラウザがリソースを取得する際の判断フローです。
リクエスト発生
│
├── キャッシュにある?
│ │
│ ├── No → サーバーにリクエスト
│ │
│ └── Yes → キャッシュはfresh?
│ │
│ ├── Yes → キャッシュを使用
│ │
│ └── No → 条件付きリクエスト
│ │
│ ├── 304 → キャッシュを使用
│ │
│ └── 200 → 新しいレスポンスを使用
#ヒューリスティックキャッシュ
Cache-ControlやExpiresが指定されていない場合、ブラウザは「ヒューリスティック(経験則)」でキャッシュ期間を推測します。
# 一般的な計算式
キャッシュ期間 = (現在時刻 - Last-Modified) × 10%
# 例: Last-Modifiedが100日前
キャッシュ期間 = 100日 × 10% = 10日
予測できない動作を避けるため、常に明示的にCache-Controlを指定することが推奨されます。
#まとめ
- HTTPキャッシュはパフォーマンス向上とサーバー負荷軽減に重要
- ブラウザキャッシュ(プライベート)と共有キャッシュ(CDN等)がある
- Cache-Controlヘッダーでキャッシュの動作を制御
- fresh(有効期限内)とstale(期限切れ)の状態がある
- DevToolsのNetworkタブでキャッシュ状態を確認できる
#次のステップ
HTTPキャッシュの基本がわかったところで、次はCache-Controlディレクティブを詳しく学びましょう。no-cacheとno-storeの違い、publicとprivateの使い分けなど、実務で必要な知識を身につけます。