rake资产:预编译很慢

时间:2011-09-24 06:40:18

标签: ruby-on-rails-3.1 asset-pipeline

命令“rake assets:precompile”对我来说非常慢。特别是在我的Amazon EC2 Micro生产服务器上,它没有很多处理器资源。在EC2上,我必须在每次部署期间等待1分钟或更长时间,仅用于此预编译任务。有没有办法让它更快?

之前我使用Jammit来压缩/缩小css和js。 Jammit在同一个网站和服务器上的工作速度提高了近10倍。

3 个答案:

答案 0 :(得分:30)

如果您不需要加载Rails环境,则应使用以下命令禁用它:

config.assets.initialize_on_precompile = false
编辑:我刚刚写了一个宝石来解决这个问题,称为turbo-sprockets-rails3。它只通过重新编译已更改的文件来加速assets:precompile,并且只编译一次以生成所有资产。

如果你可以帮助我测试turbo-sprockets-rails3宝石,那就太棒了,如果你有任何问题请告诉我。

答案 1 :(得分:10)

在预编译过程中有一个bug in Rails 3.1.0包含太多文件。如果您拥有许多资产js和css资产,这可能是速度缓慢的原因。

另一个是Sprockets(执行编译的gem)更复杂,并且必须允许更多选项--scss,coffeescript和erb。因此我怀疑连接和缩小会更慢。

根据建议,如果文件仍然存在问题,您可以在部署文件之前对其进行预编译。

答案 2 :(得分:1)

我的解决方案是从预编译中排除application.js .css和任何其他与应用程序相关的资产。这样我就可以使用rake assets:precompile一次来预编译与引擎相关的资产。

然后在每次部署时,我使用一个简单的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