ブラウザキャッシュの仕組みについてまとめた
Web開発において、ページの読み込み速度は非常に重要になります。
そのためにもブラウザのキャッシュは効率的なWebサイト運営に不可欠な機能です。
ブラウザのキャッシュには次のHTTPヘッダを設定することができます。
- Expiresヘッダ
- Cache-Controlヘッダ
- Last-Modifiedヘッダ
- ETagヘッダ
これらのキャッシュには強いキャッシュと弱いキャッシュで分類が可能です。
「Expires」「Cache-Control」は強いキャッシュであり、「Last-Modified」「ETag」は弱いキャッシュに分類できます。
強いキャッシュと弱いキャッシュ
強いキャッシュは設定された期間内は完全にローカルキャッシュを利用して、サーバーへのリクエストを行いません。
一方で弱いキャッシュはキャッシュされたリソースの検証が必要であり、ETagやLast-Modifiedヘッダを利用してリソースの有効性を確認するための条件付きリクエストを行います。これにより、レスポンスを小さくすることが可能です。
強いキャッシュを使うヘッダ
強いキャッシュではブラウザは一度リソースを確保するとマシン内部にキャッシュをします。このキャッシュが有効になるとHTTPサーバーにリクエストをしなくなります。
Expiresヘッダ
Expiresヘッダは、リソースが古くなる具体的な日時を指定することでキャッシュの有効期限を設定します。たとえば、次のように設定します。
Expires: Fri, 03 May 2024 06:11:17 GMT
この設定により、指定された日時まではサーバーにリクエストを送ることなく、ブラウザはキャッシュされたリソースを使用します。
このキャッシュは、インターネット接続が不安定な環境で非常に有効ですが、クライアントとサーバー間で時刻設定が異なる場合は、期限設定が意図した通りに機能しない可能性があります。
Cache-Controlヘッダ
Cache-Controlヘッダは、キャッシュの挙動をより詳細に制御できるヘッダです。最も一般的な利用方法は「max-age」パラメータで、リソースが新鮮であると見なされる最大時間(秒)を指定します。
Cache-Control:max-age=604800
この設定では、リソースは1週間キャッシュされ、その期間はサーバーへのリクエストが発生しません。Expiresヘッダの時刻ずれの問題を解決するために、Cache-Controlヘッダが推奨されます。
強いキャッシュを削除するテクニック
基本的に強いキャッシュはサーバー側から削除はできないのですが、次の手法で擬似的に削除が可能です。それはリクエストするリソースのURLにトークンを付与してURLを変更することです。
例えば、HTML内にimage.pngというリソースがあったとします。
<img src="image.png"
この画像のキャッシュをクリアするには、このHTMLファイルを変更してこの画像を呼び出す箇所に次のような変更を加えます。
<img src="image.png?123456789"
このようにトークンを付与することで、リソースのURLが異なるので、以前に設定されたファイルのキャッシュにヒットしなくなります。
実際の運用ではファイルのバージョン名を付与したりします。
<img src="image.png?v=1.2.3"
弱いキャッシュを使うヘッダ
これまでの強いキャッシュでは一度ブラウザでキャッシュが有効になると、基本的にはサーバー側でキャッシュをクリアできない問題がありました。
これから紹介する弱いキャッシュを使うヘッダでは条件付きHTTPリクエストを使うことで、サーバー側からキャッシュをクリアすることが可能となっています。
Last-Modifiedヘッダ
Last-Modifiedヘッダは、リソースが最後に変更された日時を示します。この情報を利用して、サーバーとブラウザはキャッシュされたコンテンツが最新かどうかを判断できます。
Last-Modified: Fri, 03 May 2024 06:11:17 GMT
ブラウザはこの日時を記録し、次に同じリソースを要求する際にIf-Modified-Sinceヘッダをリクエストに付加して、この日時をサーバーに送信します。サーバーはこの情報を利用して、リソースが変更されていなければ304 Not Modifiedステータスコードを返し、ブラウザはキャッシュを利用します。
この方法の利点は、リソースが更新されていない場合、全体のデータを再送信することなくキャッシュの利用が可能であることです。
しかし、秒単位で頻繁に更新されるようなリソースには適しておらず、また、時刻のずれが原因で不必要にリソースが再読み込みされる場合があります。
ETagヘッダ
ETag(Entity Tag)ヘッダは、リソースの特定のバージョンを一意に識別するための識別子です。Last-Modifiedヘッダよりも精度が高いため、リソースが微妙に変更された場合の検出に適しています。
ETag: "686897696a7c876b7e"
ブラウザはこのETagを保持し、次にリソースを要求する際にIf-None-Matchヘッダを通じてETagを送信します。サーバーはETagが一致するかを確認し、一致する場合は304 Not Modifiedを返してキャッシュ利用を許可します。
まとめ
ブラウザは以下のフローチャートに沿ってキャッシュの利用を行います。
Discussion