Reputation: 37339
The command "rake assets:precompile" works very slow for me. Especially on my Amazon EC2 Micro production server which does not have a lot of processor resources. On EC2 I have to wait 1 minute or more during each deployment just for this precompile task alone. Is there a way to make it faster?
Previously I used Jammit to compress/minify css and js. Jammit worked nearly 10 times faster on the same web site and servers.
Upvotes: 26
Views: 14112
Reputation: 13803
If you don't need to load the Rails environment, you should disable that with:
config.assets.initialize_on_precompile = false
EDIT: I've just written a gem to solve this problem, called turbo-sprockets-rails3. It speeds up your assets:precompile
by only recompiling changed files, and only compiling once to generate all assets.
It would be awesome if you could help me test out the turbo-sprockets-rails3 gem, and let me know if you have any problems.
Upvotes: 30
Reputation: 678
My solution is to exclude application.js .css and any other application related assets from from precompilation. So that i can use rake assets:precompile
once to precompile engine related assets only.
Then on each deploy i use a simple rake task to build any application related assets and merge them into 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
To specify which assets to compile i use a YAML configuration file (config/assets.yml
):
eg.
---
- site/site.css
- admin/admin.css
- site/site.js
- admin/admin.js
Upvotes: 1
Reputation: 10493
There is a bug in Rails 3.1.0 that includes too many files in the precompile process. This could be the reason for the slowness if you have many assets js and css assets.
The other is that Sprockets (the gem doing the compilation) is more complex and has to allow for more options - scss, coffeescript and erb. Because of this I suspect it will be slower doing just concatenation and minification.
As suggested, you could precompile the files before deploying them if this is still an issue.
Upvotes: 10