2011-09-24 120 views
25

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

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

+2

你可以在部署之前预编译你的资产 –

+1

对,我想过这个。但我不知道如何轻松地将预编译资产部署到生产环境。我正在使用capistrano,每次它都会将预编译的资产提交给git。我担心的是,在这种情况下,git存储库将会快速增长,并保留以前所有资产的历史记录。这不仅仅是css/js - 而且还包括所有的资产图片。 – Evgenii

+2

对我来说也是非常慢(135,987ms = ~2分钟)。在部署之前,我将不得不考虑预编译......我也很关心将它们添加到git中,主要是因为这会给git日志添加很多噪音。我建议不要将它们添加到git中 - 只需从本地主机将rsync目录作为cap部署脚本的一部分添加到Web服务器。 –

回答

30

如果您不需要加载Rails环境,你应该禁用与:

config.assets.initialize_on_precompile = false 

编辑:我刚写了一个宝石来解决这个问题,叫turbo-sprockets-rails3。它仅通过重新编译更改的文件来加速您的assets:precompile,并且只编译一次即可生成所有资产。

如果你能帮我测试一下turbo-sprockets-rails3宝石,并且让我知道你是否有任何问题,那将会非常棒。

+3

你的宝石非常棒。用d3解决了我的问题,并进行了预编译。谢啦 – chaostheory

10

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

另一个是Sprockets(编译gem)更复杂,必须考虑更多选项 - scss,coffeescript和erb。正因为如此,我怀疑它只会串联和缩小而变慢。

如上所述,如果仍存在问题,您可以在部署文件之前进行预编译。

+0

谢谢你的解释。我也认为它很慢,因为它需要在生产环境中加载rails环境,而Jammit并不是这种情况。无论如何,我不会回到Jammit。我很喜欢资产管道。 – Evgenii

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