web-dev-qa-db-ja.com

Rails本番環境でconfig.assets.compile = trueを使用するのはなぜですか?

Rails newによってインストールされるデフォルトのRailsアプリには、本番環境でconfig.assets.compile = falseがあります。

そして、物事を行う通常の方法は、アプリをデプロイする前にrake assets:precompileを実行し、すべてのアセットパイプラインアセットがコンパイルされていることを確認することです。

では、本番環境でconfig.assets.compile = trueを設定するとどうなりますか?

もうprecompileを実行する必要はありません。 Ibelieveが発生するのは、アセットが最初に要求されたときにコンパイルされます。これは初めてのパフォーマンスヒットになります(そして、それを行うには通常、運用環境でjsランタイムが必要です)。しかし、これらの欠点以外に、アセットが遅延コンパイルされた後、そのアセットへの以降のアクセスはすべてthinkになります noパフォーマンスヒット、アプリのパフォーマンスは、この最初のヒットレイジー後のプリコンパイル済みアセットとまったく同じになりますコンパイル。 これは本当ですか?

不足しているものはありますか?本番環境でconfig.assets.compile = trueを設定しない他の理由はありますか?本番環境でJSランタイムを使用しており、代わりにアセットのfirstアクセスのパフォーマンス低下のトレードオフを受け入れたい場合precompileを実行する必要はありませんが、これは理にかなっていますか?

176
jrochkind

ガイドのその部分を書きました。

本番環境でのライブコンパイルは絶対に避けたいものです。

コンパイルが完了したら、次のようになります。

/ assets内のファイルに対するすべてのリクエストは、スプロケットに渡されます。 firstリクエストごとに、すべてのアセットがコンパイルされ、キャッシュに使用されるRails(通常はファイルシステム)にキャッシュされます。

後続のリクエストでは、Sprocketsはリクエストを受信し、フィンガープリントされたファイル名を検索し、アセットを構成するファイル(画像)またはファイル(cssおよびjs)が変更されていないことを確認し、キャッシュバージョンがあればそれを提供します。

つまり、アセットフォルダー内のeverythingandプラグインで使用されるベンダー/アセットフォルダー内です。

正直なところ、コードの速度は最適化されていないため、これは多くのオーバーヘッドです。

これは、資産がクライアントに送信される速度に影響を与え、サイトのページ読み込み時間に悪影響を及ぼします。

デフォルトと比較してください:

アセットがプリコンパイルされ、コンパイルがオフの場合、アセットはコンパイルされ、public/assetsにフィンガープリントされます。 Sprocketsは、フィンガープリントされたファイル名のプレーンのマッピングテーブルをRailsに返し、Railsはこれをファイルシステムに書き込みます。マニフェストファイル(Rails 3のYMLまたはRails 4のランダム化された名前のJSON)は、起動時にRailsによってメモリにロードされ、アセットヘルパーメソッド。

これにより、正しいフィンガープリントされたアセットを使用したページの生成が非常に高速になり、ファイル自体の提供はファイルシステムからのWebサーバーの高速化になります。どちらもライブコンパイルよりも劇的に高速です。

パイプラインとフィンガープリンティングを最大限に活用するには、Webサーバーに遠い将来のヘッダーを設定し、jsファイルとcssファイルのgzip圧縮を有効にする必要があります。 Sprocketsは、サーバーが使用するように設定できるアセットのgzip圧縮バージョンを作成し、リクエストごとにそうする必要をなくします。

これにより、可能な限り高速で、可能な限り小さいサイズでクライアントにアセットが送信され、ページのクライアント側の表示が高速化され、(将来のヘッダーで)リクエストが削減されます。

したがって、ライブコンパイルしている場合は次のようになります。

  1. 非常に遅い
  2. 圧縮不足
  3. ページのレンダリング時間に影響します

Versus

  1. できるだけ早く
  2. 圧縮された
  3. サーバーから圧縮された音声を削除します(オプション)。
  4. ページのレンダリング時間を最小限にします。

編集:(コメントをフォローすることへの回答)

パイプラインcouldは最初のリクエストでプリコンパイルするように変更されますが、そうするためのいくつかの大きな障害があります。 1つは、フィンガープリントされた名前のルックアップテーブルが必要であるか、ヘルパーメソッドが遅すぎることです。オンデマンドコンパイルのシナリオでは、新しいアセットがコンパイルまたはリクエストされるたびにルックアップテーブルに追加する何らかの方法が必要になります。

また、すべてのアセットがコンパイルされて適切な場所に配置されるまで、誰かが不明な期間、遅いアセット配信の価格を支払う必要があります。

デフォルトでは、すべてをコンパイルする価格が一度にオフラインで支払われますが、一般の訪問者に影響を与えることはなく、物事が始まる前にすべてが機能することを保証します。

契約を破るのは、実稼働システムに多くの複雑さを追加することです。

[編集、2015年6月]デプロイ中のコンパイル時間が遅いソリューションを探しているため、これを読んでいる場合は、ローカルの資産。これに関する情報は アセットパイプラインガイド にあります。これにより、変更がある場合にのみローカルでプリコンパイルし、それをコミットして、プリコンパイルの段階なしで高速にデプロイできます。

249
Richard Hulse

プリコンパイルでオーバーヘッドを減らすため。

Precompile everything initially with these settings in production.rb
# Precompile *all* assets, except those that start with underscore
config.assets.precompile << /(^[^_\/]|\/[^_])[^\/]*$/

その後、*。html.erbまたは "/assets/web.png"の "/assets/stylesheet.css"として画像とスタイルシートを使用できます。

7
dbKooper

Herokuを使用している場合:

Herkouにデプロイする場合、コンパイルされたアセットが含まれていない場合(つまり、public/assetsがコミットされていない場合)、デプロイ中にプリコンパイルが自動的に行われるため、config.assets.compile = trueは不要です。

Herokuのドキュメントは here です。 dynoリソースの負荷を取り除くには、 CDN をお勧めします。

5
William Denniss

最初にヒットした後でも、プリコンパイルと同じではありません。ファイルはファイルシステムに書き込まれないため、Webサーバーから直接提供することはできません。キャッシュエントリを読み取るだけの場合でも、一部のRubyコードは常に関与します。

1

config.asset.compile = falseを設定

Gemfileに追加

group :assets do gem 'turbo-sprockets-Rails3' end

バンドルをインストールする

rake assets:precompileを実行します

次に、サーバーを起動します

1
Mohammed Saleem

ディレクトリトラバーサルの脆弱性を開いているため、- https://blog.heroku.com/Rails-asset-pipeline-vulnerability

0
Aurel Branzeanu

公式から ガイド

最初のリクエストで、上記の開発で概説したようにアセットがコンパイルおよびキャッシュされ、ヘルパーで使用されるマニフェスト名が変更されてMD5ハッシュが含まれます。

スプロケットは、Cache-Control HTTPヘッダーをmax-age = 31536000に設定します。これにより、このコンテンツ(提供されるファイル)を1年間キャッシュできることをサーバーとクライアントブラウザー間のすべてのキャッシュに通知します。これの効果は、サーバーからのこのアセットに対するリクエストの数を減らすことです。アセットはローカルブラウザキャッシュまたは中間キャッシュに存在する可能性が高くなります。

このモードはより多くのメモリを使用し、デフォルトよりパフォーマンスが低いため、お勧めしません。

また、デプロイに Capistrano を使用する場合、プリコンパイル手順はまったく問題ありません。それはあなたのためにそれの世話をします。あなたはただ走る

cap deploy

または(セットアップに応じて)

cap production deploy

そして、あなたはすべて設定されています。それでも使用しない場合は、チェックアウトすることを強くお勧めします。

0