おおいしつかさ


旅行とバイクとドライブと料理と宇宙が好き。
Ubie Discoveryのプログラマ。
Share:  このエントリーをはてなブックマークに追加

RailsのETag

 kaeruspoonのフロントエンドのパフォーマンスチューニングの続き。
 AmazonやYoutubeやニコニコ動画などの画像をキャッシュするようにしてDNSlookupを減らしたのと、Expiresも付与してあげたらYSlowの測定結果がB(80)になりました。最初はFランクだったのに。
 そういえばRailsがなにやら勝手にETagをつけてたみたいなので探ってみたら、actionpack-2.1.0/lib/action_controller/response.rbで以下のような処理をしていた。

    private  
      def handle_conditional_get!  
        if body.is_a?(String) && (headers['Status'] ? headers['Status'][0..2] == '200' : true)  && !body.empty?  
          self.headers['ETag'] ||= %("#{Digest::MD5.hexdigest(body)}")  
          self.headers['Cache-Control'] = 'private, max-age=0, must-revalidate' if headers['Cache-Control'] == DEFAULT_HEADERS['Cache-Control']  

          if request.headers['HTTP_IF_NONE_MATCH'] == headers['ETag']  
            self.headers['Status'] = '304 Not Modified'  
            self.body = ''  
          end  
        end  
      end  

どうもレスポンスのbodyの内容のMD5値をETagにしているみたい。kaeruspoonでは独自のAmazon広告が毎回違う内容で入るので、あまり意味がないです。ETagは全然使わない方針なので、config/initializers/response.rbを作ってオーバライドしておきました。

module ActionController  
  class AbstractResponse #:nodoc:  
    private  

    def handle_conditional_get!  
      if body.is_a?(String) && (headers['Status'] ? headers['Status'][0..2] == '200' : true)  && !body.empty?  
        self.headers['Cache-Control'] = 'private, max-age=0, must-revalidate' if headers['Cache-Control'] == DEFAULT_HEADERS['Cache-Control']  
      end  
    end  
  end  
end