我的部署速度很慢,至少需要3分钟.部署期间缓慢的Capistrano任务是assets资源 :预编译.这可能需要99%的总部署时间.我怎样才能加快速度?我应该在本地机器上预编译我的assets资源 ,并将它们添加到我的git回购中吗?

编辑:向我的应用程序添加config.assets.initialize_on_precompile = false.rb文件将预编译时间缩短了半分钟,但仍然很慢.

推荐答案

这个 idea 是,如果你不改变你的assets资源 ,你不需要每次都重新编译它们:

这是git部署的solution that Ben Curtis propose个选项:

 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.

#!/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'

因此,在开发过程中,您不会为预编译的assets资源 提供服务.

Ruby-on-rails相关问答推荐

如何在Rails中创建没有字符串的查询

Rails6.1|有没有一种方法可以判断哪些关联已经加入到一个范围中?

为什么 2 个关键字参数被解释为 1?

使用带有 Paper Trail gem 的子类

为什么 Rails 执行器不能识别内核的改进?

Rspec期望()与期望{}

Rails - 按连接表数据排序

默认情况下,如何在 Rails 中使 cookie 安全(仅限 https)?

单击表格行(使用 bootstrap 程序)时,如何使用模式显示数据?

是否有与 PHP 的 isset() 等效的 Rails?

Rails:在 lib 目录中记录代码?

Redis 引发需要 NOAUTH 身份验证错误,但没有设置密码

使用 Rails 时,在 Ruby 中处理常量的最佳方法是什么?

如何检测我的代码是否在 Rails 3 的控制台中运行?

如何在 Ruby on Rails 的内存缓存存储中列出键?

Heroku Postgres 错误:PGError:错误:关系组织不存在(ActiveRecord::StatementInvalid)

ruby/ruby on rails 内存泄漏检测

submit_tag rails 表单中的 bootstrap 图标

在 GIT 中处理 Rails db/schema.rb 文件的正确方法是什么?

是否可以输出rake db:migrate产生的 SQL 更改脚本?