ruby-on-rails - 加速 Assets :precompile with Rails 3. 1/3.2 Capistrano 部署

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

我的部署速度很慢,至少需要 3 分钟。部署期间缓慢的 Capistrano 任务是 asset:precompile。这可能花费了总部署时间的 99%。我怎样才能加快速度?我应该在本地计算机上预编译我的 Assets 并将它们添加到我的 git 存储库中吗?

编辑:将 config.assets.initialize_on_precompile = false 添加到我的 application.rb 文件中,预编译时间减少了半分钟,但仍然很慢。

最佳答案

这个想法是,如果您不更改 Assets ,则无需每次都重新编译它们:

这是solution that Ben Curtis propose对于使用 git 的部署:

 namespace :deploy do
      namespace :assets do
        task :precompile, :roles => :web, :except => { :no_release => true } do
          from = source.next_revision(current_revision)
          if releases.length <= 1 || capture("cd #{latest_release} && #{source.local.log(from)} vendor/assets/ app/assets/ | wc -l").to_i > 0
            run %Q{cd #{latest_release} && #{rake} RAILS_ENV=#{rails_env} #{asset_env} assets:precompile}
          else
            logger.info "Skipping asset pre-compilation because there were no asset changes"
          end
      end
    end
  end

这是另一种基于 Assets 年龄的方法 ( https://gist.github.com/2784462 ):

set :max_asset_age, 2 ## Set asset age in minutes to test modified date against.

after "deploy:finalize_update", "deploy:assets:determine_modified_assets", "deploy:assets:conditionally_precompile"

namespace :deploy do
  namespace :assets do

    desc "Figure out modified assets."
    task :determine_modified_assets, :roles => assets_role, :except => { :no_release => true } do
      set :updated_assets, capture("find #{latest_release}/app/assets -type d -name .git -prune -o -mmin -#{max_asset_age} -type f -print", :except => { :no_release => true }).split
    end

    desc "Remove callback for asset precompiling unless assets were updated in most recent git commit."
    task :conditionally_precompile, :roles => assets_role, :except => { :no_release => true } do
      if(updated_assets.empty?)
        callback = callbacks[:after].find{|c| c.source == "deploy:assets:precompile" }
        callbacks[:after].delete(callback)
        logger.info("Skipping asset precompiling, no updated assets.")
      else
        logger.info("#{updated_assets.length} updated assets. Will precompile.")
      end
    end

  end
end

如果您希望在本地预编译 Assets ,您可以使用此任务:

namespace :deploy do
  namespace :assets do
    desc 'Run the precompile task locally and rsync with shared'
    task :precompile, :roles => :web, :except => { :no_release => true } do
      from = source.next_revision(current_revision)
      if releases.length <= 1 || capture("cd #{latest_release} && #{source.local.log(from)} vendor/assets/ app/assets/ | wc -l").to_i > 0
        %x{bundle exec rake assets:precompile}
        %x{rsync --recursive --times --rsh=ssh --compress --human-readable --progress public/assets #{user}@#{host}:#{shared_path}}
        %x{bundle exec rake assets:clean}
      else
        logger.info 'Skipping asset pre-compilation because there were no asset changes'
      end
    end
  end
end 

另一个有趣的方法是使用git hook。 例如,您可以将此代码添加到 .git/hooks/pre-commit 中,它会检查 Assets 文件中是否存在任何差异,并最终预编译它们并将它们添加到当前提交中。

#!/bin/bash

# source rvm and .rvmrc if present
[ -s "$HOME/.rvm/scripts/rvm" ] && . "$HOME/.rvm/scripts/rvm"
[ -s "$PWD/.rvmrc" ] && . "$PWD/.rvmrc"

# precompile assets if any have been updated
if git diff-index --name-only HEAD | egrep '^app/assets' >/dev/null ; then
  echo 'Precompiling assets...'
  rake assets:precompile:all RAILS_ENV=production RAILS_GROUPS=assets
  git add public/assets/*
fi

如果您决定使用此方法,您可能需要更改 config/environments/development.rb 添加:

config.assets.prefix = '/assets_dev'

这样在开发过程中您就不会提供预编译资源。

关于ruby-on-rails - 加速 Assets :precompile with Rails 3. 1/3.2 Capistrano 部署,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9016002/

相关文章:

ruby-on-rails - Accepts_nested_attributes_for 和 has_many 多态

ruby-on-rails - capistrano3 : Don't know how to build task 'deploy:create_db'

ruby-on-rails - 如果我关闭终端,在 Heroku 上启动的 rake 任务会继续运行

ruby-on-rails - 使用 add_foreign_key : 'column "user_id"referenced in foreign key constraint does not exist' 进行 Rails 迁移

ruby - 如何在 link_to 中添加逗号

ruby-on-rails - rails 3.1 ActionController::RoutingError(没有路由匹配 [GET] "/assets/rails.png"):

ruby-on-rails - 如何在 ubuntu 中为 rails 3.1.3 应用程序加载 sqlite3 控制台?

ruby-on-rails - 在任何源中都找不到timers-1.1.0 (Bundler::GemNotFound)

ssh - 多服务器部署 : asking ssh password for each server

ruby-on-rails - 在 Rails 中,如何制作 :mobile views to fallback default views when not found?