こんにちは。チームのパフォーマンスチューニングを任せたとき、誰もが最初は「JSのバンドルサイズを削ろう」「画像の遅延読み込みを入れよう」と頑張るよね。もちろんそれも大事なんだけど……ふと立ち止まって考えてみてほしい。
「リロードした瞬間、なぜか画面が真っ白になる時間がある」「サーバー側では304を返しているのに、体感速度が一向に改善しない」。
こういう泥臭い壁にぶつかったとき、僕たちフロントエンドエンジニアが本当に理解していなければならないのは、「ブラウザのキャッシュ戦略とレンダリングの切っても切れない関係」なんだ。
今日は、HTTPキャッシュの仕様の表面的なおさらいじゃない。ブラウザが内部のメモリやストレージとどう会話して、DOM構築やレンダリングのクリティカルパスをどう駆け抜けているのか、その裏側のリアルな挙動を一緒に解き明かしていこう。現場ですぐに使える実践的な知見を詰め込んだから、ぜひ最後までついてきてほしい。
—
1. レンダリングの命運を握る「キャッシュ階層」の正体
僕たちが普段何気なく見ているWebページがブラウザに表示されるまでには、途方もない数のステップを踏んでいる。HTMLをフェッチし、パースしてDOMツリーを作り、CSSOMとマージして……と続くわけだが、その最初のステップである「HTMLの取得」の時点で勝負の8割は決まっている。
ネットワークをまたぐ通信(Network Fetch)は、どんなに高速な回線を使っても数ミリ秒〜数百ミリ秒のオーバーヘッドが発生する。ここでブラウザがどう動くか、そのキャッシュの階層構造を頭に叩き込んでおこう。
[ ブラウザの処理フロー ]
1. Memory Cache (RAM直結、超高速だがタブ閉じで消える)
↓ (Hitしなけりゃ次へ)
2. Disk Cache / HTTP Cache (SSD等、永続化される)
↓ (有効期限切れ or なければ次へ)
3. Network (サーバーへリクエスト = 最も重い)
Memory Cache と Disk Cache の生々しい挙動
- Memory Cache:
今開いているタブのメモリ上に存在する。CSSや画像、JSなどがここにヒットすると、ネットワークコストは完全に「ゼロ」になり、パース処理へダイレクトに突入できる。ただし、タブを閉じると消える儚い存在だ。
- Disk Cache(HTTP Cache):
OSのディスク(SSD/HDD)に保存される。`Cache-Control` や `ETag` などのHTTPヘッダーのルールに従って、「まだ使えるか?」を判定する。ネットワークを跨がない分ネットワークコストはないが、ディスクI/Oのわずかなオーバーヘッドがある。
現場でよくある勘違いが、「とりあえずすべてのリソースをキャッシュさせればいいんでしょ?」というもの。実はこれがレンダリングを遅延させる罠になることがある。例えば、レンダリングブロックを引き起こすクリティカルなCSSがDisk Cacheに眠っているとき、ブラウザはディスクからデータを読み込むまでの微小な待ち時間を強制される。
—
2. キャッシュがレンダリングの「クリティカルパス」に与える影響
HTMLパーサーが上から順にコードを読み進めていくとき、`` や `