web-dev-qa-db-ja.com

rakeアセット:プリコンパイルが遅い

コマンド「rakeassets:precompile」は私にとって非常に遅く動作します。特に、プロセッサリソースがあまりないAmazon EC2Micro本番サーバーでは。 EC2では、このプリコンパイルタスクだけのために、各デプロイ中に1分以上待つ必要があります。それを速くする方法はありますか?

以前は、Jammitを使用してcssとjsを圧縮/縮小していました。 Jammitは、同じWebサイトとサーバーでほぼ10倍高速に動作しました。

25
Evgenii

Rails環境をロードする必要がない場合は、次のコマンドで無効にする必要があります。

config.assets.initialize_on_precompile = false

編集:私はこの問題を解決するために turbo-sprockets-Rails と呼ばれるgemを書いたところです。変更されたファイルを再コンパイルするだけで、assets:precompileを高速化し、1回だけコンパイルしてすべてのアセットを生成します。

turbo-sprockets-Rails gemをテストするのを手伝ってくれて、何か問題があれば教えていただければ素晴らしいと思います。

30
ndbroadbent

Rails 3.1. のバグがあり、プリコンパイルプロセスに含まれるファイルが多すぎます。これが、多くのアセットjsがあり、 cssアセット。

もう1つは、Sprockets(コンパイルを行うgem)がより複雑であり、scss、coffeescript、erbなどのより多くのオプションを許可する必要があることです。このため、連結と縮小だけを行うと遅くなると思います。

提案されているように、これがまだ問題である場合は、ファイルをデプロイする前にプリコンパイルすることができます。

10
Richard Hulse

私の解決策は、application.js.cssおよびその他のアプリケーション関連のアセットをプリコンパイルから除外することです。 rake assets:precompileを1回使用して、エンジン関連のアセットのみをプリコンパイルできるようにします。

次に、デプロイごとに、単純なrakeタスクを使用して、アプリケーション関連のアセットを構築し、それらをmanifest.ymlにマージします。

namespace :assets do
  task :precompile_application_only => :environment do
    require 'sprockets'

    # workaround used also by native assets:precompile:all to load sprockets hooks 
    _ = ActionView::Base

    # ==============================================
    # = Read configuration from Rails / assets.yml =
    # ==============================================

    env           = Rails.application.assets
    target        = File.join(::Rails.public_path, Rails.application.config.assets.prefix)
    assets        = YAML.load_file(Rails.root.join('config', 'assets.yml'))
    manifest_path = Rails.root.join(target, 'manifest.yml')
    digest        = !!Rails.application.config.assets.digest
    manifest      = digest


    # =======================
    # = Old manifest backup =
    # =======================

    manifest_old = File.exists?(manifest_path) ? YAML.load_file(manifest_path) : {}

    # ==================
    # = Compile assets =
    # ==================

    compiler = Sprockets::StaticCompiler.new(env,
                                            target,
                                            assets,
                                            :digest => digest,
                                            :manifest => manifest)
    compiler.compile

    # ===================================
    # = Merge new manifest into old one =
    # ===================================

    manifest_new  = File.exists?(manifest_path) ? YAML.load_file(manifest_path) : {}

    File.open(manifest_path, 'w') do |out|
       YAML.dump(manifest_old.merge(manifest_new), out)
    end

  end
end

コンパイルするアセットを指定するには、YAML構成ファイル(config/assets.yml)を使用します。

例えば。

---
- site/site.css
- admin/admin.css
- site/site.js
- admin/admin.js
1
mcasimir