rake assets:precompile需要很长时间才能完成。

15

在我的开发沙盒中

RAILS_ENV=production rake assets:precompile

完成这项任务需要超过4分钟时间,这是否正常?在Heroku上执行该任务需要超过10分钟的时间,并且有时会超时。是否有任何方法可以分解它和/或加速它?

更新

我对编译的CSS和JS阶段进行了分析。

3.7 s        js
175 s            css

这里的数字是通过仪器监测得出的。
----------------------
/Users/bradphelan/.rvm/gems/ruby-1.9.2-p180@gobbq/gems/sprockets-2.1.2/lib/sprockets/processing.rb
----------------------
266     # Assign a compressor to run on `application/javascript` assets.
267     #
268     # The compressor object must respond to `compress` or `compile`.
269     def js_compressor=(compressor)
270       expire_index!
271  
272       unregister_bundle_processor 'application/javascript', :js_compressor
273       return unless compressor
274  
275       register_bundle_processor 'application/javascript', :js_compressor do |context, data|
276  
277         timeit "js" do
278           compressor.compress(data)
279         end
280  
281       end
282     end

并且

    ----------------------
    /Users/bradphelan/.rvm/gems/ruby-1.9.2-p180@gobbq/gems/sprockets-2.1.2/lib/sprockets/processing.rb
    ----------------------
    241  
    242     # Assign a compressor to run on `text/css` assets.
    243     #
    244     # The compressor object must respond to `compress` or `compile`.
    245     def css_compressor=(compressor)
    246       expire_index!
    247  
    248       unregister_bundle_processor 'text/css', :css_compressor
    249       return unless compressor
    250  
    251       register_bundle_processor 'text/css', :css_compressor do |context, data|
    252         timeit "css" do
    253           compressor.compress(data)
    254         end
    255       end
    256     end

timeit调用是进行计时的附加部分。

def timeit context
  s = Time.now
  yield.tap do 
    e = Time.now
    d = e - s
    puts "#{d*1000}\t #{context}"
  end
end

这里有一些关于提高性能的建议...不算是答案,更像是一些指针:[1]: https://dev59.com/BWHVa4cB1Zd3GeqPjyAF [2]: https://dev59.com/hV7Va4cB1Zd3GeqPJ3bj [3]: http://www.ruby-forum.com/topic/2538285 - ScottJShea
实际上,其中一个链接看起来像是一个可能的候选者。我怀疑Rails应用程序以某种方式被多次加载。http://www.ruby-forum.com/topic/2538285#1026719 - bradgonesurfing
2
将 config.assets.compress = false 设置为false,可以将编译时间降至40秒。因此,JavaScript压缩需要3分20秒。我们在这里没有编译boost C++库!! - bradgonesurfing
我不认为那是答案。我的意思是,我仍然想要压缩功能。它需要这么长时间,需要修复而不是关闭该功能。 - bradgonesurfing
不,似乎Rails默认使用Sass :: Rails :: CssCompressor来压缩CSS,这是个坏家伙! - bradgonesurfing
显示剩余2条评论
4个回答

6
我是在Rails 3.2.13上工作的 - 我遇到了CSS压缩花费极长时间的问题。要解决此问题,需要在Gemfile中添加以下内容:
gem 'yui-compressor'

在config/environments/production.rb文件中:
config.assets.css_compressor = :yui
config.assets.js_compressor = :yui

没有这些更改的 rake assets:precompile: 325 秒

具有这些更改的 rake assets:precompile: 79 秒

没有压缩的 rake assets:precompile: 45 秒


这对我没有用。时间大约相同,大约6分钟! - Isaac Betesh
你确定你在生产模式下进行了预编译吗? - Yoni Baciu
我正在使用Capistrano。我非常确定。 - Isaac Betesh
1
我更新了我的答案,包括config.assets.js_compressor = :yui,这使得差异很大。 - Yoni Baciu
谢谢。我尝试了 config.assets.js_compressor = :yui,我的 Capistrano 部署过程从 4 分钟降至约 45 秒。 - Isaac Betesh
这是一个很好的提示。我的生产编译时间从25分钟缩短到了5分钟。ckeditor有大量的资源,这就是导致问题的原因。我还不得不使用0.11版本的yui-compressor来解决一个问题,即当编译空的JS文件时,0.12版本的yui压缩器(2.4.8)会崩溃。yui压缩器2.4.7没有这个问题。 - Matt Schwartz

3

解决方法似乎是通过猴子补丁将标准的Sass压缩引擎替换掉。我在application.rb文件的顶部添加了以下内容:

module Sass
  module Rails
    class CssCompressor
      def compress(css)
        css
      end
    end
  end
end

在猴子补丁之前,文件大小的差异为124k,在猴子补丁后为125k,速度提高了一个数量级。

Heroku的资产构建时间已经降至52秒,虽然仍然不太理想,但比15分钟要好。 - bradgonesurfing
3
不能帮助处理 Ruby 1.9.3 和 Rails 3.2.1。 - Paul

1
最好的选择是本地编译,像平常一样提交和部署,并在生产环境中禁用预编译任务。我现在正在为所有我的生产应用程序执行此操作。
为了避免在开发模式下提供已编译的资产(覆盖您需要的动态管道编译),请执行以下操作。
在 development.rb 文件中放置以下行:
config.assets.prefix = "/dev-assets"

这将覆盖 application.rb 中设置的任何内容(通常为“/assets”)。

您还需要在 application.rb 中添加以下内容:

config.assets.initialize_on_precompile = false

这将停止任务尝试连接到您的数据库。(如果您在资产中引用ActiveRecord模型,则要小心,因为这不起作用)。

这些更改允许您在本地编译和提交资产到您的存储库,并在您的工作开发树中拥有这些文件,但是仍然向Sprockets发送开发请求。此外,只有在实际更改时才需要预编译和提交。

参见我的博客文章


请阅读注释和详细信息。CSS压缩器存在问题,无论是在本地编译还是在生产环境中都需要很长时间。 - bradgonesurfing

1

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接