Cache Controlについてまとめる
Shared キャッシュと Localキャッシュの違い
設定の意味
- max-age
- s-maxage
- must-revalidate
- stale-while-revalidate
- no-cache
- no-store
- immutable
キャッシュの流れ
- レスポンスを保存する
- 保存したレスポンスを再利用する
キャッシュの種類
- local (private) キャッシュ
- 特定のユーザー専用のキャッシュ
- ブラウザのキャッシュなどが該当する
- shared キャッシュ
- 複数のユーザがレスポンスを再利用するためのキャッシュ
- ProxyやCDNのキャッシュなどが該当する
キャッシュの設定
- public
- レスポンスをどのキャッシュ (local、shared ともに) にも保存し、再利用できる
- private
- レスポンスを local キャッシュのみに保存し、再利用できる
- no-cache
- レスポンスをどのキャッシュ (local、shared ともに) にも保存できる
- キャッシュが stale (有効期限が過ぎている) かどうかに関わらず、再利用時に必ずサーバーに確認を取る必要がある
- no-store
- レスポンスをどのキャッシュ (local、shared ともに) にも保存させない
個人情報などを扱うページについては、localキャッシュのみを許可する private
を設定する。どこにもキャッシュされたくない場合は、no-store
を設定する。(no-cache
ではない!!)
ちなみに、なにもCache-Control を設定しない場合、レスポンスはどこかでキャッシュされる可能性があるので、キャッシュされたくない値を使うときは注意する。
キャッシュのライフサイクル周りの設定
- max-age
- キャッシュの有効時間の設定 (local、shared キャッシュともに有効)
- 1 ヶ月 (2592000) 、1年 (31536000) とかの値をセットすればよい
- s-maxage
- shared キャッシュの有効時間の上書きに使う
- must-revalidate
- キャッシュが stale (有効期限が過ぎている) の時に、再利用時に必ずサーバーに確認をとる必要がある
max-age=0
は、キャッシュが無効にはならず、Request Collapsingの場合にキャッシュが返ってしまうことに注意する。
CDNからオリジンへのリクエストの処理中に、同じURLに対してリクエストが発生すると、最初のレスポンスを待って、2つ目以降のリクエストにも同じレスポンスが返される仕様になっていました。
must-revalidate
は、一見 no-cache
と似ているけど、キャッシュが stale かどうかで挙動が異なる。
細かい設定
どちらも詳細はjxckさんのブログに書いてあるので、適宜読み直すと良さそう。
stale-while-revalidate
キャッシュが stale になったら、指定された期間内は stale なキャッシュを返しつつ、バックグラウンドでキャッシュを更新する設定。
「キャッシュは効かせたいが、なるべく新鮮なリソースを提供したい。」などといった要望に対処する
immutable
キャッシュが有効期限内であればリロード時もキャッシュを再利用させる設定。ブラウザがリロードする際は、キャッシュが fresh (有効期限内) か stale かどうかに関わらず、条件付きリクエストを発行し、キャッシュの検証を行う。
no-cache
や must-revalidate
の設定のときに行われている、キャッシュの再利用時にサーバーにキャッシュの有効性を問い合わせるリクエストを条件付きリクエストと呼ぶ。
有効性の評価については、リソースが変更された最終時刻のタイムスタンプかリソースのハッシュ値を利用する。リソースが変更された最終時刻のタイムスタンプの場合は、最初のリソース取得のときにサーバーが Last-Modified
でタイムスタンプをブラウザに返し、送られた Last-Modified
を使って If-Modified-Since
ヘッダを付与した条件付きリクエストをサーバーに送信する。サーバーでは、タイムスタンプの時刻をつかってキャッシュが有効がどうか判断する。リソースのハッシュ値の場合は、最初のリソース取得のときにサーバーが Etag
でタイムスタンプをブラウザに返し、送られた Etag
を使って If-Non-Match
ヘッダを付与した条件付きリクエストをサーバーに送信する。サーバーでは、ハッシュ値をつかってキャッシュが有効がどうか判断する。
キャッシュについては、以下のフローチャートを元に設定するのも良さそう
Expire ヘッダーは、Cache Control ヘッダーで上書きされるので、あんまり知っている必要はなさそう。