Closed7

Cache Controlについてまとめる

nissy-devnissy-dev

キャッシュの流れ

  1. レスポンスを保存する
  2. 保存したレスポンスを再利用する

キャッシュの種類

  • 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 を設定しない場合、レスポンスはどこかでキャッシュされる可能性があるので、キャッシュされたくない値を使うときは注意する。

nissy-devnissy-dev

キャッシュのライフサイクル周りの設定

  • max-age
    • キャッシュの有効時間の設定 (local、shared キャッシュともに有効)
    • 1 ヶ月 (2592000) 、1年 (31536000) とかの値をセットすればよい
  • s-maxage
    • shared キャッシュの有効時間の上書きに使う
  • must-revalidate
    • キャッシュが stale (有効期限が過ぎている) の時に、再利用時に必ずサーバーに確認をとる必要がある

max-age=0 は、キャッシュが無効にはならず、Request Collapsingの場合にキャッシュが返ってしまうことに注意する。

CDNからオリジンへのリクエストの処理中に、同じURLに対してリクエストが発生すると、最初のレスポンスを待って、2つ目以降のリクエストにも同じレスポンスが返される仕様になっていました。

https://speakerdeck.com/kazeburo/cdn-in-mercari

must-revalidate は、一見 no-cache と似ているけど、キャッシュが stale かどうかで挙動が異なる。

nissy-devnissy-dev

細かい設定

どちらも詳細はjxckさんのブログに書いてあるので、適宜読み直すと良さそう。

stale-while-revalidate

キャッシュが stale になったら、指定された期間内は stale なキャッシュを返しつつ、バックグラウンドでキャッシュを更新する設定。

「キャッシュは効かせたいが、なるべく新鮮なリソースを提供したい。」などといった要望に対処する

https://blog.jxck.io/entries/2016-04-16/stale-while-revalidate.html

immutable

キャッシュが有効期限内であればリロード時もキャッシュを再利用させる設定。ブラウザがリロードする際は、キャッシュが fresh (有効期限内) か stale かどうかに関わらず、条件付きリクエストを発行し、キャッシュの検証を行う。

https://blog.jxck.io/entries/2016-07-12/cache-control-immutable.html

nissy-devnissy-dev

no-cachemust-revalidate の設定のときに行われている、キャッシュの再利用時にサーバーにキャッシュの有効性を問い合わせるリクエストを条件付きリクエストと呼ぶ。

有効性の評価については、リソースが変更された最終時刻のタイムスタンプかリソースのハッシュ値を利用する。リソースが変更された最終時刻のタイムスタンプの場合は、最初のリソース取得のときにサーバーが Last-Modified でタイムスタンプをブラウザに返し、送られた Last-Modified を使って If-Modified-Since ヘッダを付与した条件付きリクエストをサーバーに送信する。サーバーでは、タイムスタンプの時刻をつかってキャッシュが有効がどうか判断する。リソースのハッシュ値の場合は、最初のリソース取得のときにサーバーが Etag でタイムスタンプをブラウザに返し、送られた Etag を使って If-Non-Match ヘッダを付与した条件付きリクエストをサーバーに送信する。サーバーでは、ハッシュ値をつかってキャッシュが有効がどうか判断する。

nissy-devnissy-dev

Expire ヘッダーは、Cache Control ヘッダーで上書きされるので、あんまり知っている必要はなさそう。

このスクラップは2022/01/19にクローズされました