2014年03月14日 20:00 [Edit]

Tips - 静的リソースのURIに?をつけるべからず

asin:4774142042
Webを支える技術

HTTP、URI、HTML、そしてREST
山本陽平

であればなおのことこの実装はNG。

ブラウザのキャッシュを利用できれば、余分なリクエストを減らすことができます。はてなブログでは、なるべく長い間ブラウザにキャッシュを保存するために、JavaScriptなどの一部の種類のファイルのレスポンスに、以下のようなヘッダを指定しています。

はてなブログにおけるページ表示速度改善の取り組みについて - Hatena Developer Blog
はてなブログではJavaScriptを配信する際には、上記のURLのように、?よりあとの部分にabc078624b2a746c618156847827166bのようなバージョンIDを付与しています。JavaScriptが変更されるバージョンとともにURLも変化するため、古いキャッシュが利用されることはありません。

なぜこれが問題になるか。

プロクシーサーバーがキャッシュしてくれなくなるかも知れないから。

Googleもわざわざこのように注意喚起している。

Optimize caching - Make the Web Faster — Google Developers

Don't include a query string in the URL for static resources.

Most proxies, most notably Squid up through version 3.0, do not cache resources with a "?" in their URL even if a Cache-control: public header is present in the response. To enable proxy caching for these resources, remove query strings from references to static resources, and instead encode the parameters into the file names themselves.

やるのであれば、 /js?abc078624b2a746c618156847827166b とかではなく /js-abc078624b2a746c618156847827166b などとすべきということ。

ヘッダーの時間指定に関しても、はてなの実装は同文書からはみ出ている。

Cache-Controlヘッダ、Expiresヘッダではキャッシュの有効期限を10年先に指定しています。

同文書の勧告はまさにはてなの意図とも合致するのだが、野方図に有効期限を長くすべしとも言っていない。

Set Expires to a minimum of one month, and preferably up to one year, in the future. (We prefer Expires over Cache-Control: max-age because it is is more widely supported.) Do not set it to more than one year in the future, as that violates the RFC guidelines.

一年以上にするのはRFCガイドライン違反とある。

Set the Last-Modified date to the last time the resource was changed. If the Last-Modified date is sufficiently far enough in the past, chances are the browser won't refetch it.

Last-Modified に関しては、本来の意味、つまりリソースの最終更新日時を指定すべきとも言っている。はてなの中の人のほとんどが生まれてさえいなかったであろうtime(0)にせよなんて言ってない。

で、その実装なのだが、ヘッダーを見るかぎりはてなではこの部分を Hatena::Epic::Global::Static という(Perl?)モジュールで動的にやっているようだ。ならばなおのこと、日時や時間も動的に--ただしリソースが無変更ならば同じ値を返すよう--設定すべきではなかろうか。

Dan the Officious


この記事へのトラックバックURL