HTTPキャッシュを個人的にまとめる
はじめに
キャッシュについて自分の言葉でどこまで説明できるかを試すと、浅い理解だったため改めてまとめてみます。
⚠️個人の技術記事なので細かい誤りはご容赦ください。
HTTPキャッシュとは
Webページを公開する際には、サーバがWebページをホスティングします。
HTTPキャッシュとは、Webページにアクセスする際にブラウザなどの私的なキャッシュやCDNなどの共有キャッシュがサーバからの応答を保存し、同等のリクエストがある際に再利用できる仕組みです。
そのWebページの実体はファイル群であり、そのファイル数は多くなります。ブラウザが毎回問い合わせをして表示をすると、通信トラフィックが増大して応答時間の増大やオリジンサーバへの負荷増大に繋がります。
そこで登場するのがキャッシュです。キャッシュは保存済みの応答を再利用し、WebサーバからETagやLast-Modifiedによる304 Not Modifiedの応答が来た際は、保存したキャッシュを使用してWebページを表示します。キャッシュはHTTPヘッダでコントロールされ、その内容に応じて直接サーバにリクエストを送ったり、保存した応答をそのまま表示したりします。
下記に簡単なキャッシュのイメージを図示します。
Cache-Controlヘッダフィールド
Cache-Controlヘッダフィールドとは、ブラウザのキャッシュを管理するHTTPヘッダです、下記に示すような属性があります。
| 名称 | 内容 |
|---|---|
public |
共有キャッシュを含め保存可能。 |
private |
共有キャッシュは保存不可/ブラウザは保存可 |
max-age=n |
キャッシュの鮮度を秒数で指定をする。失効後は検証し、変更あれば200で再取得、なければ304。 |
no-cache |
キャッシュの保存は可能、ただし再利用時は検証必須。 |
no-store |
キャッシュをしない。どのキャッシュも保存禁止。 |
immutable |
変更されていないことを示す。Firefox/Safariは解釈可能。Chromium系は未対応。 |
stale-while-revalidate=秒 |
期限切れでも即時に古い応答を返し、裏で再検証して次回以降に反映する。 |
s-maxage |
共有キャッシュに対する寿命を上書きする。 |
must-revalidate |
失効後は必ず検証(オフラインでも再利用禁止) |
ETag
ETagはWebサーバが付与するエンティティタグです。
クライアントは If-None-Match で提示し、キャッシュされた情報に変更があるか否かの判断に役立ちます。ETagの多くはハッシュ化された値(多くがハッシュだが必須ではない)であり、コンテンツが更新されるとその値も変わります。
ブラウザがETagを保持しており、サーバに問い合わせをする場合にETagの値が同一であれば304のNot Modifiedを返してブラウザに保存されたキャッシュを利用します。
万が一、変更がある場合は200 OKを返して更新されたWebページを表示して、ブラウザのキャッシュも更新をします。
Last-Modified
Last-Modified は最終更新日時を表します。クライアントは If-Modified-Since を送り、更新されていなければ 304を返します。
ETagとLast-Modifiedが両方ある場合は ETagが優先されます。また、Last-Modified は秒精度や時計のずれの影響を受けやすいという懸念があります
Vary
同一URLでもクライアントごとに異なる結果を返すのがVaryヘッダフィールドです。使用している端末や言語によって異なる内容を返す必要があるため、その差異の根拠となるリクエストヘッダ名をキャッシュに教えます。例: Vary: Accept-Encoding, Accept-Language。
改めてフローを眺める
まとめ
今回はキャッシュについてまとめました。皆さんの学習の参考になれば幸いです。
参考文献
Discussion