角待ちは対空

おもむろガウェイン

max-ageはどのようなコンテンツに設定すべきか

可能なコンテンツすべて、だと思っている。

「キャッシュは麻薬」という言葉があるが、大麻OKな国もある的な(多分ぜんぜん違う)。要するに用法用量を守ってちゃんと利用しなきゃいけない。モルヒネも適切に使えば麻酔。

我々はギガが減る時代に生きているのでサーバーに余裕があるからと言ってクライアントにキャッシュをさせないのは間違ってる。サーバーのリソース的にリクエストが捌ききれないのでキャッシュを使うのではなく、ユーザー体験のためにキャッシュを使う時代。

HTTPキャッシュにはExpirationモデルとValidationモデルがあるわけだけど、可能ならば当然前者を使うべき。後者でも「ギガが減る」かという意味では対して変わらないがレスポンスの待ち時間が存在する以上、やはり前者を最初に考えたい。

ではどのようなコンテンツがExpirationモデルで、つまりmax-ageが設定できるだろうか?

まず思い浮かぶのがURLを変えられるコンテンツ。キャッシュはURLをキーにするのでURLが別ならばキャッシュは当然別になる。したがってURLを変更できるのであればいつstaleにすべきかなんて考えず遠い未来までキャッシュ期間を設定してしまって良い。

URLを変えられるコンテンツに該当するのは単純にロゴなどのアセット(ロゴを変えたくなったらファイル名を変えれば良い)などが挙げられるが、意外に見落としがちなのはjsやcssファイルである。jsやcssファイルのパスを変更するのは大変だがクエリパラメータを変更すれば良い。クエリパラメータもURLである。

jsやcssが変更されるのはデプロイ時ほとんどだと思われるのでjsファイルのハッシュ値を計算してクエリパラメータとして付与すればデプロイ時に新しいjsファイルを確実に読み込ませつつ、Expirationモデルのキャッシュをさせることが可能である。

他にはどんなコンテンツにmax-ageを設定させられるか考えると、実は究極的にはURLを変えられるコンテンツしかない。言い換えれば(見方を変えれば)同一のURLでは必ず同一のコンテンツが返ってくるリソースということである。(もちろんmax-ageを少なめに設定してある程度更新が遅れても見えても構わないなどの戦略は取れるが、原則的には、という話でおいとく)

この大原則を踏まえるとどのようにコンテンツを配信すべきかが見えてくる。つまり一度生成したURLでは必ず同一のコンテンツを返し、コンテンツの更新はすべきではない。これは動的なアプリケーションのHTMLやAPIのレスポンスでは不可能だが、例えば画像などでは設計次第では十分可能である。

ちなみに更新というとコンテンツが新しくなることを想像しがちだが削除もありうる。コンテンツが新しくならない設計は十分可能だが、削除されないまでいくと実質不可能だと思われる。しかしながら、すでにオリジンが404だがクライアントにはキャッシュが見えているという状況は、クライアントがキャッシュを参照し別コンテンツを見ている場合に比べて問題になることは少なく感じる。なので削除したコンテンツのキャッシュが残ることは許容してしまえば楽になれる。そう思ってるのはお前だけと言われたら反論はできない。

以上、まとめると

  • max-ageつけられないか最初に考えよう
  • max-ageつけても問題にないURLとコンテンツの関係を設計しよう
    • 404は許容してもいいんじゃないかな

blog.yux3.net