Researching a new form of HTTP caching optimization - Phusion Blog を読んだ。議論を呼んでいた Turbocaching についてちょっと詳しい説明があった。
Vary ヘッダを使うとキャッシュを返していいかどうかをリクエストの内容によって切り替えられるが、 Cookie ヘッダは Google Analytics とかのユーザートラッキング情報で頻繁に変更されるので、 Cookie ヘッダ全体を Vary の対象に含めてしまうとキャッシュを返してよいケースでもキャッシュが使えなくなる。
というリサーチを経て、アプリケーション側で任意の名前の Cookie をセットし、 Passenger の起動時オプションで同じ Cookie 名を指定することで、 Passenger が Cookie ヘッダをパースして指定された名前の Cookie の値だけをチェックし、キャッシュを使えるか判断する、というのが Passenger 5 のパフォーマンス改善の目玉である Turbocaching の仕組みらしい。
Vary を工夫するというアプローチはアプリケーションの実装次第で Passenger 以外のウェブサーバでも利用できそうな気がする。試してないけどこんなコードでどうにかならないだろうか。
class SessionsController < ApplicationController def create cookie[:user_id] = current_user.id end end class UsersController < ApplicationController def show @user = current_user response.headers['Vary'] = ['Accept-Encoding', 'X-MyApp-UserId'] end end
$.ajax({ url: '/users/me', type: 'GET', headers: { 'X-MyApp-UserId': $.cookie('user_id') }, dataType: 'json' })
アプリケーションのフロントエンドを Single Page Application ぽく実装して Ajax と PushState を使えばキャッシュの利用機会を増やせる、というのは、実際そういう作りのアプリケーションを仕事でいくつか開発運用してきた身としては、言うほど簡単じゃないよ、と思った。