--- layout: old_post title: 「Railsの画面生成を10倍高速化する方法」をESIで実装する permalink: /tatsuya/show/368-rails-10-esi ---
やっと最近余裕が出てきて、溜まってた「あとで読む」リストを消化中ですが、1個面白そうなブログがあったので試してみる
Advanced Rails Caching.. on the Edge
どうも「Railsは重いのでESIでページキャッシュを組み合わせてカバーしよう、ESIのmongrel実装とRails用ESIタグ出力プラグインを開発中だ」と言ってるみたい。発端としては少し前の「 Railsの画面生成を10倍高速化する方法 」このエントリに似た話で
・Railsは遅い、Rubyが遅くてRoutingが遅くてRDBとRHTMLが遅い。
・なので、出来るだけページキャッシュでさばきたい(フロントのWebサーバのみで処理)
・でもユーザ固有情報を表示するのが難しい(ようこそ○○さん)
ここでRails抜きで動的ページを処理するアイデアが幾つか出て来てて
・JavaScript使ってクライアントサイドで動的処理をしようよ派 (現実の世界の Rails、第 2 回: 高度なページ・キャッシング)
・サーバサイドで完結させたい派(Railsは基本的なHTMLをページキャッシュとして出力、何らかの手段で二次処理を加える)
・SSIを使う(Railsの画面生成を10倍高速化する方法)
・ESIを使う(Advanced Rails Caching.. on the Edge)
等の試行錯誤がされてるみたい。(厳密に言うとESIの人は「更新頻度が少なくても問題無い部分をESIでTTL指定してキャッシュしよう」と言ってる気がするけど気にしない)
ということで、今回はESIを試してみる。ESIのmongrel実装が開発されてるらしいので、まずインストール。
wget http://mongrel-esi.googlecode.com/files/mongrel-esi-0.0.5.gem sudo gem install mongrel-esi-0.0.5.gem
適当なRailsアプリへ移動し、index.htmlを書き換える。
cd /home/my/rails/app/path ----index.html----- <h1>Welcome ESI!!</h1> <p><esi:include src="/welcome/now" max-age="45"/></p>
mongrel_esiを起動
mongrel_esi start ** Starting Mongrel listening at 0.0.0.0:2000
ブラウザで http://localhost:2000/index.html を開く、、と例のタグの部分へ 「http://localhost:2000/welcome/now というページが無い」とエラーが出る筈。esi:includeタグ部分へmongrel_esiが外部ページを読み込んでいるので成功。読み込まれるページを用意する
./script/generate controller welcome now ----welcome_controller.rb---- def now render :text => "#{Time.now}" end
再度表示すると、上手く読み込まれる。45秒間キャッシュする設定にしたので(max-age=45)その間は時刻が同じで表示される。これで無事、静的ページへ45秒に1回更新の動的部分を組み込むことができた。
次はRails用のESIタグ出力プラグイン ”fragmentFu” をインストール、/welcome/index に実装してみる
./script/plugin install http://mongrel-esi.googlecode.com/svn/trunk/plugin/fragment_fu ----/app/view/welcome/index.html.erb---- <h1>Welcome ESI!!</h1> <p><%= render :esi => {:action => "now"}, :ttl => 45.seconds %> </p>
これで上でhtmlに記述したタグと同じESIタグが出力される。あとはこれをページキャッシュに指定すればOK。但し「ようこそ○○さん」等のユーザ固有処理を行うためにはSSIと同じようにESI + PHPを組み合わせる等工夫が必要になるかもしれない。ちなみにESIではCookieの値や、クエリーストリングなんかを処理に組み込めるので
#クエリーストリングをページ読み込みのURLに利用 <p><%= render :esi => "/users/name/$(QUERY_STRING{my_name})" %> </p> #Cookieをページ読み込みのURLに利用 <p><%= render :esi => "/users/home/$(HTTP_COOKIE{UserID})" %> </p>
等、動的に読み込む外部ページのURLを変えることである程度「Rails & 2段階のページキャッシュ」で完結できる、かも。まあ別にSSIだろうがESIだろうが結局は何でも良いんだけど、しいていうならコードはRailsで完結させたいな。さらに理想を言えば
初回)/welcome/index と /users/show/ユーザID/name をページキャッシュ
初回以降)/welcome/indexの静的ページキャッシュへ、 /users/show/$(HTTP_COOKIE{UserID})/name のページキャッシュをESIで動的読み込み(ようこそ○○さん)
ユーザが名前を変更)/users/show/ユーザID/name をキャッシュ作り直し
(他のページからも /users/show/ユーザID/name を利用するがキャッシュは一つ)
というのがやりたい。Rails出力は初回のみにして基本ページキャッシュを表示する、しかもmongrel + Railsな手慣れたツールで完結させたい。もう少し考えてみよう。
参考リンク
W3C ESI Language Specification 1.0 ESIのW3C仕様
FragmentFu - Fun with Fragments mongrel_esiとRailsの連携、チュートリアル有
現実の世界の Rails、第 2 回: 高度なページ・キャッシング JavaScriptでページキャッシュを2次処理
Railsの画面生成を10倍高速化する方法 SSI + PHP でページキャッシュを2次処理
Oracle - Edge Side Includes用のJESIタグ ESIのOracle Application Server実装資料