Briswell Tech Blog

ブリスウェルのテックブログです

CloudFrontとブラウザのキャッシュについて

暑い日が続きますね。キュウリがとても美味しい季節となりました。
キュウリは、汗と共に失われる水分を補給し体の冷却を助けてくれます。

今回は、キャッシュ(頻繁にアクセスするデータを一時的に保存して次回のアクセスを速くする仕組み)についてです。

なんとなく、効率化という観点でキュウリとキャッシュ似ているような気がします。こじつけかしらん。

tech.briswell.com

前回はCloudFrontの利用メリットについて書きましたが、キャッシュの仕様についても、正しく理解しておかないと、CDNのCloudFrontを最大限に活かすことができません。

  • CloudFront側のキャッシュ(エッジキャッシュ)
  • ブラウザ側のキャッシュ

それぞれ見ていきましょう。

1. CloudFront側のキャッシュ

CloudFrontは、以下が同じ場合に同一リクエストと判断し、キャッシュをクライアント側に返却します。

  • URL
  • HTTPメソッド
  • 特定の HTTPヘッダー(任意設定)
  • クエリ文字列(任意設定)
  • cookie(任意設定)

キャッシュ期間は、TTL設定(最低存続時間、最大存続時間、デフォルトの存続時間)で定義します。

Time to live (TTL) 設定:
キャッシュキーの管理 - Amazon CloudFront

CloudFrontのInvalidation(1か月に送信した無効化パスのうち最初の1,000 件は無料)を実行することで、CloudFrontのキャッシュを手動削除することも可能です。

1-1. キャッシュが存在しない場合
  • 設定された条件(オリジンリクエストポリシー)に従い、オリジンサーバーにリクエストを転送しデータを取得します。
  • 取得したデータをクライアントに返却します。
  • 取得したデータを設定された条件(キャッシュポリシー)に従ってキャッシュします。
1-2. 有効なキャッシュが存在する場合
  • キャッシュデータをクライアントに返却します。
1-3. 無効な(期限切れ)キャッシュが存在する場合
  • 設定された条件(オリジンリクエストポリシー)に従い、オリジンサーバーにリクエストを転送しデータを取得します。
  • オリジンサーバーのデータがキャッシュと同じ場合
    • キャッシュデータをクライアントに返却します。
    • キャッシュデータのTTLを更新します。
  • オリジンサーバーのデータがキャッシュと違う場合
    • 取得したデータをクライアントに返却します。
    • 取得したデータを設定された条件(キャッシュポリシー)に従ってキャッシュします。

2. ブラウザ側のキャッシュ

ブラウザ側のキャッシュは、Cache-Controlの設定で制御することができます。

この設定を理解しておかないと...
「オリジンサーバーの画像ファイルを差し替えてCloudFrontのキャッシュも最新のはずなのに、いつまで経ってもブラウザのキャッシュ画像を表示している。CloudFrontにもリクエストしていない。なぜ?」
となります。

AWS CLIを使用してS3(オリジンサーバー)にファイルをアップロードする場合、以下のようにCache-Controlヘッダーを設定することができます。

aws s3 cp /path/to/your/file s3://yourbucket/yourpath --cache-control max-age=3600

設定値について記載します。

no-cache

返却値をキャッシュできますが、キャッシュを使用する前に、オリジンサーバーでの検証が必要です。これにより、古いコンテンツが使用されることを防ぐことができます。

no-store

全てのキャッシュを無効にします。コンテンツがセキュアな情報(パスワードやクレジットカード情報など)を含む場合等に使用されます。

max-age=[seconds]

キャッシュを有効とみなす時間を指定します。
例えば
「3600」を指定すると、3600秒(1時間)がキャッシュ保持期間となります。
「0」を指定すると、最初から既に期限切れの状態なので、毎回変更がないか問合せします。

Cache-Controlヘッダーがない場合

この場合、どのような挙動になるのでしょうか?

RFC 7234 - Hypertext Transfer Protocol (HTTP/1.1): Caching

If the response has a Last-Modified header field (Section 2.2 of [RFC7232]), caches are encouraged to use a heuristic expiration value that is no more than some fraction of the interval since that time. A typical setting of this fraction might be 10%.

  • Last-Modifiedヘッダーの日時
  • Dateヘッダーの日時

の差の10%の値をキャッシュの有効期間として定めることが多いとのことです。
コンテンツが変更されない期間が長くなるほど、ブラウザキャッシュの有効期限も長くなる(より長くキャッシュされる)ということですね。

そのため、何らかの事情で、Cache-Controlヘッダーを設定できない場合、
ブラウザ側で古いコンテンツを差し替えて新しいコンテンツを表示するためには...

  • 何らかの操作時にブラウザキャッシュをクリアする処理を入れる
  • CloudFrontからの画像取得パスにクエリ文字列(例:test.jpg?20230713)を入れる

等の対策が必要になってきます。

キャッシュって奥が深いですね!