ブラウザキャッシュの制御
基本的なことのようで意外と細かいことを理解していなかったりする. RFC 2616 - 13. Caching in HTTP
Last-Modified and If-Modified-Since
HTTP レスポンスヘッダーに Last-Modified
が付いていると、リクエストに If-Modified-Since
が付くようになって、(サーバーが対応していれば)更新されていない場合は 304 Not Modified
が返ってくる。このキャッシュメカニズムを利用する場合はサーバーと通信する必要はある。 Cache-Control: no-cache
や max-age=0
はこの動作には影響しないので注意。
ETag and If-None-Match
レスポンスに ETag
が付いていると、リクエストに If-None-Match
が付与されるようになる。のはずなんだけど、Chrome も Safari も動かないよ... Firefox では動く。 ETag の周りには “” をつけるのかね、普通は。これも罠だな.... ちなみに ETag はユーザのトラッキングにも使えたりする。
Cache-Control
(HTTP 1.1 以降) public だとか private だとか max-age だとかをカンマ区切りで指定する。
no-store
レスポンスを保存してはならないことを表す。これが指定されるとリソースのキャッシュは全くされなくなる。
no-cache
キャッシュが有効であるかの再確認を conditional-request で行わなければならないことを表す。 no-cache という名前だが一切キャッシュされないという意味ではない。一切キャッシュが起こらないのは no-store である。
max-age
キャッシュの有効性の確認を行わずに、キャッシュを利用して良い期間の長さ。 max-age はあくまで、サーバーに問い合わせないでキャッシュを利用しても良い期限を設定するだけである。max-age を超えるとキャッシュが削除されたりするわけではない。 Last-Modified が設定されている場合、max-age を超えたリソースは If-Modified-Since 付きでリクエストが行われ、304 が返ってくれば引き続きキャッシュが利用される。
Expires
Expires で指定された時刻まではサーバーへの問い合わせなしでキャッシュの利用を行う。 Cache-Control: max-age が指定されている場合は上書きされる。
Pragma: no-cache, Cache-Control
Vary
ヘッダの内容が異なっていても、同じ URL のキャッシュが存在すればブラウザはキャッシュを利用する。特定のリクエストヘッダもキャッシュのキーとして利用し、そのヘッダが異なる場合にはキャッシュを利用したくない場合には Vary ヘッダをつける必要がある。13.6 Caching Negotiated Responses
Google が推奨するキャッシュの最適化の方法
- ブラウザのキャッシュを活用するより
- CSS や JavaScript のような頻繁には変化しない外部リソースのキャッシュの最適な設定の指針 by Google
- Expires あるいは max-age を少なくとも 1 ヶ月先、できれば 1 年先に設定する(1 年より大きくするのは RFC 違反らしい)
- JavaScript, CSS の URL にハッシュ値とかバージョン番号とか適当なユニークな値を含むようにして、 更新を行った場合は HTML から参照される JavaScript, CSS の URL が変更し、キャッシュにヒットしないようにする。
- HTML ページ自体のようなブックマークされたり外部からリンクされるようなリソース (URL が変えられないリソース) のキャッシュには向かない。