Drowsy Dog's Diary

any note, any thought

2014年2月4日
by kazoo
0 comments

[rails]アセットパイプラインのためのApache最適化設定

アセットパイプライン

「アセット」とは Web サーバ上の静的コンテンツのこと。具体的には、画像、CSS、Javascript などのファイル。

アセットパイプラインはバージョン3.1以降の Rails に備わっている機能で、主な役目はアセットを圧縮・結合すること、そしてファイルのフィンガープリントをファイル名に組込むこと。この2つの操作を「コンパイル」と呼んでいる。

は、アセットをコンパイルするコマンド。
app/assets/images/
app/assets/stylesheets/
app/assets/javascripts/
app/assets/fonts/

などにあるファイルが「プリコンパイル」される。

コンパイルによって、 app/assets/images/ 以下の画像ファイルには MD5 ハッシュをファイル名に付加して /public/assets/ にコピー。また CSS/JS は、それぞれの拡張子(.scss, .erb, .coffee など)に応じた方法でファイルが変換され、CSS や JS ごとの結合が行われた後、Minification(空白、改行、コメントの除去等)された後に gzip 圧縮される。

このようにすることで、アセットの通信量を最小化しつつ、ファイルの中身の変化に応じてファイル名自体が変わるので、ブラウザやプロキシサーバにキャッシュされていても古いファイルが替わらないという問題を避けられる。むしろ /assets/ 以下の URI へのアクセスに関しては、出来る限りキャッシュを推奨するのが望ましい。そのための HTTP リクエスト/レスポンスのヘッダ設定が以下のようになる。

キャッシュ設定

ここでは CentOS 想定。設定ファイルパス、URI は適当に読み替えてください。

/etc/httpd/sites-available/my_site

それぞれの意味はこんな感じ。

  • ExpiresActive… On にすると Expires および Cache-Control ヘッダを生成する
  • ExpiresDefault… Expires に設定するデフォルトの値。ここではアクセス日時+30日間
  • Header set Cache-Control… HTTP ヘッダの Cache-Control の値を上書きする。”public” は、ブラウザだけでなく Web プロクシにもキャッシュを許可する
  • Header unset Etag… HTTP ヘッダの ETag を削除する(レスポンスが ETag ヘッダを持たないようにする

圧縮設定

アセットパイプラインにおける CSS ファイルなどは圧縮・結合された上で /public/assets/ に配置される。そのとき、*.css, *.css.gz の2つのファイルが生成される。ミニフィケーションと結合だけが行われたものと、それをさらに gzip したもの。

現在多くの Web ブラウザでは、gzip形式で圧縮されたコンテンツをサーバから受け取って、それを展開してからレンダリングする機能を持っている。そういったブラウザは、Accept-Encoding リクエストヘッダに gzip あるいは x-gzip という文字を含む値をセットする。これを受け取った Apache や Nginx といった Web サーバは、その場でコンテンツを圧縮して送り返す。

しかし、アセットパイプラインを利用している場合はすでに圧縮されたファイルが存在しているので、この圧縮は CPU の無駄となる。なので、すでに圧縮済みのファイルを利用するような設定が以下となる。

/etc/httpd/sites-available/my_site

  • AddEncoding… 拡張子 .gz のファイルのエンコーディングが x-zip だと指定する。
  • Header set Vary Accept-Encodig… Vary ヘッダは、リクエストのヘッダによってレスポンスが変化することと、その基準となるリクエストヘッダを Web プロクシに教える。これによってたとえば gzip 圧縮に対応しているブラウザとしていないブラウザが同一のプロクシにアクセスしても問題が出ないようにできる
  • RewriteEngine on/RewriteCond… Accept-Encodingヘッダに gzip/x-gzip という文字を含むリクエストで、かつ末尾に .gz を加えた URI に対応するファイルが存在する場合、それを返す
  • <FilesMatch>…. 拡張子 .css.gz および .js.gz の MIME タイプを ForceType ディレクティブによって指定する

2013年9月3日
by kazoo
0 comments

[rails] ActiveSupport::CoreExtenstions::Hash::Slice

めもん。

Rails の Core Ext の Hash#slice は、引数で与えられた key だけの Hash を返す。
Controller で Request params に対して 有効なキーのみ残したいときなどに使う。

slice! は逆に、引数に与えられたキーを削除して、残された Hash を返す。

参考(v4.0):
http://railsdoc.eiel.info/active_support/core_ext/hash/#slice

ソース(3.2):
https://github.com/kazoo/rails/blob/3-2-stable/activesupport/lib/active_support/core_ext/hash/slice.rb