rake assets:预编译很慢

Posted

技术标签:

【中文标题】rake assets:预编译很慢【英文标题】:rake assets:precompile is slow 【发布时间】:2011-09-24 06:40:17 【问题描述】:

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

之前我使用 Jammit 来压缩/缩小 css 和 js。 Jammit 在相同的网站和服务器上运行速度快了近 10 倍。

【问题讨论】:

你可以在部署之前预编译你的资产 对,我想过。但我不知道如何轻松地将预编译资产部署到生产环境。我正在使用 capistrano,每次它都会将预编译的资产提交给 git。我担心的是 git 存储库在这种情况下会快速增长,保留所有以前资产的历史记录。这不仅是 css/js - 还包括所有资产图像。 这对我来说也非常慢(135,987ms = ~2 分钟)。在部署之前我必须研究预编译......我也担心将它们添加到 git 中,主要是因为这会给 git 日志添加很多噪音。我建议不要将它们添加到 git - 只需将该目录从 localhost 同步到您的网络服务器,作为 cap 部署脚本的一部分。 如果你不需要加载 Rails 环境,你应该禁用它:config.assets.initialize_on_precompile = false 【参考方案1】:

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

config.assets.initialize_on_precompile = false

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

如果您能帮我测试一下turbo-sprockets-rails3 gem,那就太好了,如果您有任何问题,请告诉我。

【讨论】:

你的宝石太棒了。用 d3 和预编译解决了我的问题。谢谢大佬【参考方案2】:

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

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

按照建议,如果这仍然是个问题,您可以在部署文件之前预编译文件。

【讨论】:

感谢您的解释。我也认为它很慢,因为它需要在生产环境中加载 rails 环境,而 Jammit 并非如此。无论如何,我不会回到贾米特。我非常喜欢资产管道。【参考方案3】:

我的解决方案是从预编译中排除 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

【讨论】:

以上是关于rake assets:预编译很慢的主要内容,如果未能解决你的问题,请参考以下文章

如何解决极其缓慢的 rake assets:在 heroku 上预编译?

我在 Open Project 源代码中遇到了 rake assets 预编译问题

rails4 rake assets 在生产环境中预编译生成错误的javascript文件

rake assets:precompile 突然失败

为啥 rake assets:precompile 需要永远?

Rails 不会编译资产,但会在日志中显示编译,rake assets:precompile not generate files