Skip to content

cdn asset host rails31

iwhurtafly edited this page Jun 23, 2012 · 4 revisions

Webのユーザビリティは、ユーザーインターフェースに限るわけではありません: ユーザビリティの大きな構成要素は、速度です。 Webでは、速度とはページのロード時間のパフォーマンスと読み替えられます。アプリケーションのコードにフォーカスすることは重要で、 ページのロード時間を劇的に改善するためのユーザーインターフェースを作り出す簡単な必勝法がたくさん存在します。

Content Delivery Network (CDN)を使うことは、サイトにある静的アセットの配信を最適化してくれます。 このことは、静的アセットへの全リクエストに対するWeb dynoの負荷を下げ、代わりに、動的コンテンツへの より多くのリクエストを処理出来るよう、dynoを解放します。

Heroku Cedar上のRails 3.1アプリケーションで、git push herokuを実行した場合、 bundle exec rake assets:precompileのRakeタスクを使うことで、ディプロイのプロセスの一環として、 アセットがプリコンパイルされます。

この記事では、Rails 3.1のコンパイル済みアセットをCDNへ移行することを一工程で可能とする asset_syncというgemの使い方をお見せします。

よりシンプルですが、パフォマーンスが劣る、アプリケーション組み込み型の静的アセットキャッシュに関しては、 [Rack::Cache and memcached in Rails 3.1+]の記事を参照して下さい。

インストール方法

Gemfileへ下記のgemを追加して下さい。:

:::ruby
gem "asset_sync"

インストール:

:::term
$ bundle install

設定

まだお持ちでなければ、S3 アカウントのサインアップを行って下さい。 その後で、config varsへ証明書の追加を行います。:

:::term
$ heroku config:add FOG_PROVIDER=AWS AWS_ACCESS_KEY_ID=xxx AWS_SECRET_ACCESS_KEY=yyy

また、バケット名を選択する必要があります。通常は、アプリ名-assetsのような感じになるでしょう。 バケットがまだ存在していないのであれば、AWS Management Consoleへサインインし、 最初にバケットを作っておく必要があります。

:::term
$ heroku config:add FOG_DIRECTORY=yourappname-assets

config/environments/production.rb内に、asset_hostを記述して下さい。:

:::ruby
config.action_controller.asset_host = "https://#{ENV['FOG_DIRECTORY']}.s3.amazonaws.com"

RailsのAssetTagHelperメソッド (image_tagのような)を使用していることを確認して下さい。 このことは、アプリのアセットが、新しいアセットホストを参照することを保証します。

デフォルト (United States)以外のS3リージョンをお使いの場合、初期化プログラムの全設定オプションについて書かれた Github上のドキュメントasset_syncを必ず参照して下さい。

アセットの同期

git push heroku masterでアプリをディプロイ後、アセットを同期することが出来ます。 データベースのマイグレーション実行前、実行後のいずれかで、下記の処理を実行して下さい。

:::term
$ heroku run rake assets:precompile
Running rake assets:precompile attached to terminal... up, run.2
Uploading: assets/application-a552e1db33b8be6a42eedf1261916f3c.js
Uploading: assets/jquery-8a50feed8d29566738ad005e19fe1c2d.min.js.gz
Uploading: assets/jquery-ui-7e33882a28fc84ad0e0e47e46cbf901c.min.js.gz
Uploading: assets/rails-bd9ad5a560b5a3a7be0808c5cd76a798.png
Uploading: assets/application-a552e1db33b8be6a42eedf1261916f3c.js.gz
Uploading: assets/jquery-8a50feed8d29566738ad005e19fe1c2d.min.js
Uploading: assets/application-ccb8034635849c44627859332fda6a01.css
Uploading: assets/jquery-ui-7e33882a28fc84ad0e0e47e46cbf901c.min.js
Uploading: assets/application-ccb8034635849c44627859332fda6a01.css.gz
Uploading: assets/manifest.yml
Done.

Heroku上でアセットがコンパイルされ、S3のバケットと同期が行われます。

ステージング環境/本番環境

複数のディプロイ(ほとんどの場合、ステージング環境と本番環境)を行っている場合、それぞれの環境に 自身のFOG_DIRECTORYを管理するよう、設定する必要があります。

$ heroku config:add FOG_DIRECTORY=yourappname-assets --remote production
$ heroku config:add FOG_DIRECTORY=yourappname-assets-staging --remote staging

Gitリモートとステージング環境/本番環境のディプロイに関しては、こちらを参照して下さい。

SSLのサポート

条件付きのアセットホストは、SSLと非SSLのアセット両方が提供されるサイトに使えます。:

:::ruby
config.action_controller.asset_host = Proc.new do |source, request|
  method = request.ssl? ? "https" : "http"
  "#{method}://#{ENV['FOG_DIRECTORY']}.s3.amazonaws.com"
end

CDNのサポート

速度を最大限出したい大規模なサイトでは、Cloudfrontを使うことでしょう。 Cloudfrontホストを入力して下さい。:

:::ruby
config.action_controller.asset_host = "http://yourhost.cloudfront.net"

ローカルでのテスト

環境変数として、設定値をセットすることで、ローカル端末のアセットを同期させることも出来ます。

:::term
$ export AWS_ACCESS_KEY_ID=xxx export AWS_SECRET_ACCESS_KEY=yyy
$ export FOG_DIRECTORY=yourapp-dev-assets

この後で、コンパイルの実施、アセットの同期を行って下さい。:

:::term
$ bundle exec rake assets:precompile
Uploading: assets/application-9f98b53212a48cc52bc1db6f3031e546.css
Uploading: assets/application-9f98b53212a48cc52bc1db6f3031e546.css.gz
Done.

ローカルのRailsアプリを起動すると、リモートのアセットホストからロードされた全てのアセットが表示されるでしょう。 (一度、全てが正常動作していることをを知ったら、外部のアセットホストを使わないよう、開発環境の設定値を戻したくなるかもしれません。 ただ、そうすると、CSSとJavaScriptに変更が入る度に、コンパイルを実行する必要が発生します。)

CSS / JS内のアセット参照

もし、CSS内でbackground imageの参照を使っているのであれば、これらが新しいアセットホストを参照するよう、 いくつかの追加設定が必要となります。私たちの手法は、新たなmultiple asset pre-processorサポートを使うこととしています。

例えば、app/assets/master.cssファイルは:

:::css
.selector {
  background: url('logo.png');
}

app/assets/master.css.erbとなるでしょう。:

:::css
.selector {
  background: url(<%= asset_path 'logo.png' %>);
}

検証結果

ブラウザからアプリを訪問してみて下さい。SafariまたはChromeで、Resourcesタブを開くと、 S3からアセットが提供されていることを確認出来るでしょう。

通常設定とアセットホストを使った場合の速度の違いを確認するために、ベンチマークテストを実施することも可能です。:

:::term
$ time curl http://my-domain.org/assets/logo.png > /dev/null

$ time curl http://my-bucket.s3.amazonaws.com/assets/logo-f3626b3c07a87edb678237aa63edb414.png > /dev/null

高度な設定

この記事では紹介しきれない、asset_syncの追加機能があります。 以下のようなことを学ぶために、完全版ドキュメントをお読み下さい。:

  • Rackspaceのサポート
  • マルチリージョンのサポート
  • gzipへの自動圧縮
  • 前回コンパイルされたファイルの保管、削除のためのフラグについて
  • 追加設定のオプションについて
Clone this wiki locally