HTTP キャッシュ
過去に取得したリソースを再使用すると、ウェブサイトやアプリケーションのパフォーマンスが大きく向上するでしょう。ウェブキャッシュは遅延やネットワークのトラフィックを削減して、リソースを表示するために必要な時間も短縮します。HTTP キャッシュを使用すると、ウェブサイトの応答性が高まります。
キャッシュの基本
キャッシュしない
Cache-Control: no-store
キャッシュを検証する
キャッシュした複製を渡す前に検証のため、キャッシュは生成元のサーバーにリクエストを送信します
Cache-Control: no-cache
または
Cache-Control: max-age=0, must-revalidate
有効期限
設定期間が過ぎたら、サーバーにリクエストして、リソースをダウンロードします。
Cache-Control: max-age=31536000
キャッシュの検証
Cache-Control: must-revalidate
Last-Modified/If-Modified-Since
リソースのレスポンスのheaderにLast-Modified
がもらえる
HTTP/1.1 200 OK
Content-Type: text/html
Content-Length: 1024
Date: Tue, 22 Feb 2022 22:22:22 GMT
Last-Modified: Tue, 22 Feb 2022 22:00:00 GMT
Cache-Control: max-age=3600
<!doctype html>
…
3600秒に過ぎたら、リソースをまたリクエストして、If-Modified-Since
を設定します。
GET /index.html HTTP/1.1
Host: example.com
Accept: text/html
If-Modified-Since: Tue, 22 Feb 2022 22:00:00 GMT
もしリソースは新しくにならなければ、304返して、フロントエンドの方はキャッシュしているリソースを使います。
HTTP/1.1 304 Not Modified
Content-Type: text/html
Date: Tue, 22 Feb 2022 23:22:22 GMT
Last-Modified: Tue, 22 Feb 2022 22:00:00 GMT
Cache-Control: max-age=3600
ETag/If-None-Match
リソースのレスポンスのheaderにETag
がもらえる
HTTP/1.1 200 OK
Content-Type: text/html
Content-Length: 1024
Date: Tue, 22 Feb 2022 22:22:22 GMT
ETag: "33a64df5"
Cache-Control: max-age=3600
<!doctype html>
…
3600秒に過ぎたら、リソースをまたリクエストして、IIf-None-Match
を設定します。
GET /index.html HTTP/1.1
Host: example.com
Accept: text/html
If-None-Match: "33a64df5"
もしリソースは新しくにならなければ、304返して、フロントエンドの方はキャッシュしているリソースを使います。
HTTP/1.1 304 Not Modified
Content-Type: text/html
Date: Tue, 22 Feb 2022 23:22:22 GMT
Last-Modified: Tue, 22 Feb 2022 22:00:00 GMT
ETag: "33a64df5"
Cache-Control: max-age=3600
フロントエンドエンジニアはキャッシュのことはあまり気にしなかった → なぜ
デフォルトキャッシュStragegyがあります: Heuristic caching
Js Bundle
- Webpack
- Vite
Webフレームワーク対応してくれます
- Rails
- Laravel
Webサーバー対応してくれます。
- Cloudfront
- CDN
リソースのレスポンスHeaderにキャッシュの設定はなにもない場合、クライアントは自分で判断します。
HTTP/1.1 200 OK
Content-Type: text/html
Content-Length: 1024
Date: Tue, 22 Feb 2022 22:22:22 GMT
Last-Modified: Tue, 22 Feb 2021 22:22:22 GMT
<!doctype html>
…
エンジニアは何もしなくてもキャッシュしてくれます。
Commonのキャッシュ方法
キャッシュしたくない場合、
Cache-Control: no-cache, no-store, must-revalidate
- 例: APIのリクエスト
- 例: index.htmlファイル
リソースを変更するときに、リソースパースを変更します。
# version in filename
bundle.v123.js
# version in query
bundle.js?v=123
# hash in filename
bundle.YsAIAAAA-QG4G6kCMAMBAAAAAAAoK.js
# hash in query
bundle.js?v=YsAIAAAA-QG4G6kCMAMBAAAAAAAoK
実際に画像はキャッシュしてくれない問題があります。
S3のpresigned urlを使います。
- S3のpresigned urlは毎回に変わるため、クライアントは毎回にリクエストを送信して画像をダウンロードします。
- 対策は: バックエンドで画像ごとに画像リンクを固定します。バックエンドでS3のpresigned urlにredirectします。
バックエンドで画像リンクがありますが、キャッシュの設定はno-cache, no-store, must-revalidate
でした。
- バックエンドのAPIはデフォルトのヘッダーの設定はキャッシュしないため、画像リンクが変わらなくても毎回にリクエストを送信します。
- 対策は画像のリンクのヘッダーはキャッシュしない設定を外します。