1. ホーム
  2. ruby-on-rails

[解決済み】Railsのプロダクションでconfig.assets.compile=true、なぜダメなのか?

2022-04-17 01:17:36

質問

でインストールしたデフォルトのRailsアプリは rails new には config.assets.compile = false を生産しています。

そして、普通のやり方は rake assets:precompile アプリをデプロイする前に、すべてのアセットパイプラインのアセットがコンパイルされていることを確認します。

では config.assets.compile = true を作成することはできますか?

を実行する必要はありません。 precompile は、もうありません。私が 信じる は、アセットが初めてリクエストされたときに、コンパイルされることになります。これは、初回のパフォーマンスに影響します(そして、一般的にこれを行うには、プロダクションでjsランタイムが必要であることを意味します)。 しかし、これらのデメリット以外では、アセットが遅延コンパイルされた後、私は 思う そのアセットへのその後のアクセスは、すべて いいえ パフォーマンスが低下すると、アプリのパフォーマンスは 全く同じ この最初の一撃の遅延コンパイルの後は、プリコンパイルされたアセットと同じです。 というのは本当でしょうか?

何か見落としていることはありませんか?他に config.assets.compile = true を使用することができますか? もし私が実運用環境でJSランタイムを持ち、そのためにパフォーマンスの低下というトレードオフを覚悟で はじめに を実行する必要がない代わりに、アセットにアクセスするための precompile ということですが、これは意味があるのでしょうか?

どのように解決するのですか?

ガイドのその部分を書いたのは私です。

本番では絶対にライブコンパイルはしないでください。

コンパイルをオンにすると、このようになります。

/assetsにあるファイルへのリクエストはすべてSprocketsに渡されます。その際 最初 をリクエストすると、それぞれのアセットがコンパイルされ、Railsがキャッシュに使っているもの (通常はファイルシステム) にキャッシュされます。

それ以降のリクエストでは、Sprocketsはリクエストを受け取り、フィンガープリントされたファイル名を調べ、アセットを構成するファイル(画像)やファイル(cssやjs)が変更されていないことを確認し、キャッシュされたバージョンがあればそれを提供しなければなりません。

それは すべて assets フォルダ内の プラグインが使用する vendor/assets フォルダにあります。

正直なところ、スピードのために最適化されたコードではないので、これはかなりのオーバーヘッドです。

これは、クライアントへのアセット転送速度に影響し、サイトのページロード時間にも悪影響を及ぼします。

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

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

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

パイプラインとフィンガープリンティングの利点を最大限に活かすには、ウェブサーバにfar-futureヘッダを設定し、jsとcssファイルのgzip圧縮を有効にする必要があります。Sprocketsは、サーバーが使用するように設定できるgzip圧縮されたバージョンのアセットを書き込み、リクエストごとにそうする必要性をなくします。

これにより、アセットをできるだけ速く、できるだけ小さなサイズでクライアントに送り、クライアント側のページ表示を高速化し、(遠距離ヘッダーを使用して)リクエストを削減します。

つまり、ライブコンパイルならそうです。

  1. 非常に遅い
  2. 圧縮性能に欠ける
  3. ページのレンダリング時間に影響を与える

対談

  1. できるだけ早く
  2. 圧縮
  3. サーバーからオーバーハードコンプレッションを削除します(オプション)。
  4. ページのレンダリング時間を最小化します。

編集部:(フォローアップコメントへの回答)

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

また、すべてのアセットがコンパイルされ、配置されるまでの未知の期間、アセットデリバリーの遅さという代償を誰かが支払わなければならないでしょう。

すべてをコンパイルする代償をオフラインで一度に支払うデフォルトでは、一般の訪問者に影響を与えず、本番前にすべてが動作することを保証します。

しかし、生産システムに多くの複雑さをもたらすということが問題なのです。

[2015年6月編集]。 もし、デプロイ時のコンパイルに時間がかかる場合の解決策を探していてこれを読んでいるのであれば、ローカルでアセットをプリコンパイルすることを検討してみてはいかがでしょうか。これに関する情報は アセットパイプラインガイド . これにより、変更があったときだけローカルでプリコンパイルし、それをコミットすれば、プリコンパイル段階を経ずに高速なデプロイが可能になります。