by ryou

キャッシュ制御に関する私的まとめ

はじめに

Googleのドキュメント読めばわかる。

HTTP キャッシュ Web Google Developers

キャッシュに関して覚えるべきヘッダー

  • キャッシュデータ使用に関するヘッダー
    • Cache-Control
    • Expires
  • キャッシュされたデータとサーバーのデータの同一性判断に関するヘッダー
    • ETag
    • Last-Modified

上記の4つ。

キャッシュデータ使用に関するヘッダー

Cache-ControlとExpiresはキャッシュデータ使用に関するヘッダー。

Cache-ControlはHTTP/1.1の仕様として定義されたもので、Expiresはそれ以前の古い仕様。

現行ブラウザでもExpiresは動作するが、Cache-Controlの方が優先される。

Cache-Control

ヘッダーは

Cache-Control: max-age=1200

だとか

Cache-Control: no-cache

みたいな感じで書く。

.htaccessで設定したい場合は

Header set Cache-Control "max-age=1200"

って形。

no-cache

めっちゃ勘違いされやすいディレクティブ。

no-cacheって名前だから「キャッシュを使わせなくする」設定って勘違いされがちだが、そうではなく「キャッシュを使う場合は必ずサーバーにキャッシュに変更がないか確認しろ」っていう設定。

no-store

こっちが「キャッシュを使わせなくする」設定。

ファイルに変更がなかろうが問答無用で最新データを取得する。

「これを設定すればクライアントとのトラブルなくなるやん!」って設定すると当然のことながらパフォーマンスがくっそ下がる。

max-age

これに関しては理解がまだあやふや。

各種ドキュメントと実際のブラウザの動作を見たところ、最後にデータを受け取ってから指定された秒数だけ「サーバーへの問い合わせ無しに」キャッシュを使用するっぽい。

例えば「max-age=60」だと60秒間「サーバーへの問い合わせ無しに」キャッシュを使用する。

サーバーに問い合わせをしないから「max-age=86400」とかすると一日間はデータの変更があろうがキャッシュが使用される。(もちろんスーパーリロードで最新のものを取りに行くし、通常のリロードもmax-ageを無視するみたいなので通常のリロードでも最新の物を取りに行く)

Expires

そのうち調べる

キャッシュされたデータとサーバーのデータの同一性判断に関するヘッダー

ETag

ファイルが更新される度に変更されるトークンを用いて同一性を判断するヘッダー

クライアント側はキャッシュデータのETagを「If-None-Match」ヘッダーに付与し、そのETagとサーバー側のデータのETagが同じであれば、サーバー側はデータ更新の必要なしと判断して304を返す。

Last-Modified

ETagとは異なり、ファイルの更新日時で同一性を判断するヘッダー

クライアント側はキャッシュデータの更新日時を「If-Modified-Since」に付与しサーバーに送信、サーバー側のファイルがキャッシュデータの送信日時より後に更新されていなければ304を返す。

キャッシュの挙動の検証の際の注意

キャッシュの挙動を確認する際は、リンクを用意してリンク遷移(同一ページへの遷移でもいいので)させた際の挙動を確認すること。

スーパーリロードでキャッシュ無効になるのは周知の事実だけど、通常のリロードでも遷移の際と挙動が異なるみたい(どうもmax-ageが無視されるらしい)。

パフォーマンスが良くなる設定はどんなのだろう

思いつくのはリソースファイル(cssやjpg等)

Cache-Control: max-age=15552000

とかmax-ageを大きくすることでそもそものサーバーへの問い合わせを少なくする。

もちろんこのままだと変更があってもリロード、スーパーリロードしない限り更新されないので、

<link rel="stylesheet" href="/common/css/style.min.css?date=1492338313">

みたいな感じでリソースファイルの末尾にファイルの更新日時を付与して、変更があった際には新規ファイルと認識してデータ取ってもらうようにする、ってのがいいのかなぁと。

多少なりとも工数かかる作業なので、トラフィックが多いパターン以外はそこまで気にしなくても良いのかもしれませんけどね。

参考

HTTP キャッシュ Web Google Developers

「Cache-Controlヘッダは仕様通り実装されていない?」のコメント