HTTP のキャッシュ(その2)
今回は前回に引き続きキャッシュについて。 Expiration モデルについて整理します。
前回の繰り返しになりますが、 Expiration モデルは食品の消費期限に似ています。しかし実際の所、このモデルは以下のように機能が多くかなり複雑です。
- プロキシサーバーのキャッシュ管理
- (セキュリティや不安定な通信環境の考慮を含む)
- クライアントによるキャッシュ制御
- バリデーションモデルとの組み合わせ
その他、 HTTP/1.0 との互換性等の考慮されている点が多数あり、ボリュームが多くなってしまいます(また正直な所、理解しきれていません…)。
そこで今回はクライアントの挙動から Expiration モデルの基本的なメカニズムの解説をしていきます。
サンプルサイト
実際にブラウザがどのようにキャッシュを行うのか、サンプルサイトを作って試してみました。
このサイトでは、背景色付の文字を表示します。背景色と文字はリクエストごとにランダムなものを返します。
実際にリクエストが投げられた場合には色や文字が変わる、という仕組みです。
一つのページには、色と文字の組が3組表示しています。外部のスタイルシート、 XMLHttpRequest の応答、それと HTML 自身に色と文字の情報が記載されています。これで、ページのリクエストの送信方法によってキャッシュの扱いが異なってもある程度認識が出来ます。
有効期限を指定する
まずは有効期限が0秒のページを表示します。この設定はページをキャッシュをさせたくない場合に良く使われます。最初にリクエストを送ると、こんな感じになります。
同じページを再度開くと、別の色になりました。サーバーから読み込んでいますが、バリデーションのためのヘッダは渡していますので、前回の手法でステータス304を返して通信量を減らす余地は残っています。
最終更新日から予測する
キャッシュの有効期限が指定されていない場合、ブラウザは最終更新日を使用してキャッシュの更新時間を予測します。一般的には、最終更新日が現在からどれだけ離れているか(どれだけ古いコンテンツか)から計算して寿命を予測します。
まずは、 Last-Modified に現在時刻をしていている場合です。
キャッシュ更新のタイミングはブラウザで事なる
HTTPのRFCによると最終更新日からのキャッシュの寿命の計算方法は任意なので、ブラウザ毎に異なります。またこの場合、最終更新日以外の要素から判断することがあります。
例えば、 Internet Explorer は XMLHttpRequest(AJAX) を使用した場合はかなり積極的にキャッシュするようです。また、 Firefox は URL に「?」を含む場合と含まない場合で挙動が異なります。
一方でサーバー側でキャッシュの有効期限を指定した場合は、大抵のブラウザ (IE/Firefox/Chrome/iPhone など) で指定通りにキャッシュしてくれます。キャッシュに残った古いファイルを使われてしまいたくない場合(動的なページのほとんどが該当するでしょう)は、有効期限を指定した方が良いでしょう。
なお、 RFC では可能な限り有効期限を指定する事を推奨しています。
感想
難しいですね。