如何调试速度慢得难以忍受的 Rails 资源预编译

2024-06-21

我正在开发一个 Rails 3.2 项目,尽管我不认为该项目很大,但近几个月来资产已经增加了相当多。资产由 JS(无咖啡脚本)和 SASS 文件组成;我们有很多图像,但从早期开始,它们出现的次数就更少了,所以我认为它们不是一个重要因素。我们可能有大约十几个库,大多数都很小,最大的是 Jquery UI JS。部署是通过 Capistrano 完成的,并且开始变得明显的是,部署到暂存阶段比部署到生产环境要快得多。为了进行说明,同时避免有关不同服务器和网络影响的因素,我只需在笔记本电脑上按顺序运行以下三个命令,如下所示:

$ time RAILS_ENV=production bundle exec rake assets:precompile
^Crake aborted!
[Note I aborted this run as I felt it was getting stupidly long...]
real    52m33.656s
user    50m48.993s
sys 1m42.165s

$ time RAILS_ENV=staging bundle exec rake assets:precompile
real    0m41.685s
user    0m38.808s
sys 0m2.803s

$ time RAILS_ENV=development bundle exec rake assets:precompile
real    0m12.157s
user    0m10.567s
sys 0m1.531s

所以我只能摸不着头脑。为什么不同的环境之间存在如此巨大的差异?我可以理解开发和分期之间的差距,但是我们的登台和生产配置是相同的。 (我应该指出,生产编译将在大约 2 小时后完成!)

虽然最终结果是让我的预编译速度更快,但我希望通过了解所有时间都花在哪里以及为什么 Rails 环境之间存在如此大的差异来实现这一目标。我看过其他关于使用不同压缩器等的帖子,但我找不到任何有关如何调试这些 rake 任务以找出时间花费在哪里并确定哪些设置可能导致如此巨大差异的信息。

我不知道人们可能需要哪些额外信息,因此如果评论询问,我会更新。 TIA

更新:下面提供的附加信息

config/environments/production.rb and config/environments/staging.rb(它们完全相同):

MyRailsApp::Application.configure do
  # Code is not reloaded between requests
  config.cache_classes = true

  # Full error reports are disabled and caching is turned on
  config.consider_all_requests_local       = false
  config.action_controller.perform_caching = true

  # Disable Rails's static asset server (Apache or nginx will already do this)
  config.serve_static_assets = true
  config.static_cache_control = "public, max-age=31536000"
  config.action_controller.asset_host = "//#{MyRailsApp::CONFIG[:cdn]}"

  # Compress JavaScripts and CSS
  config.assets.compress = true

  # Don't fallback to assets pipeline if a precompiled asset is missed
  config.assets.compile = false

  # Generate digests for assets URLs
  config.assets.digest = true

  # Enable locale fallbacks for I18n (makes lookups for any locale fall back to
  # the I18n.default_locale when a translation can not be found)
  config.i18n.fallbacks = true

  # Send deprecation notices to registered listeners
  config.active_support.deprecation = :notify
end

基本 config/application.rb 是:

require File.expand_path('../boot', __FILE__)

require 'rails/all'

if defined?(Bundler)
  # If you precompile assets before deploying to production, use this line
  Bundler.require(*Rails.groups(:assets => %w(development test)))
  # If you want your assets lazily compiled in production, use this line
  # Bundler.require(:default, :assets, Rails.env)
end
module MyRailsApp
  CONFIG = YAML.load_file(File.join(File.dirname(__FILE__), 'config.yml'))[Rails.env]

  class Application < Rails::Application

    # Custom directories with classes and modules you want to be autoloadable.
    config.autoload_paths += %W(#{config.root}/lib)
    config.autoload_paths += %W(#{config.root}/app/workers)

    # Configure the default encoding used in templates for Ruby 1.9.
    config.encoding = "utf-8"

    # Configure sensitive parameters which will be filtered from the log file.
    config.filter_parameters += [:password]

    # Enable the asset pipeline
    config.assets.enabled = true

    # Stop precompile from looking for the database
    config.assets.initialize_on_precompile = false

    # Version of your assets, change this if you want to expire all your assets
    config.assets.version = '1.0'

    # Fix fonts in assets pipeline
    # http://stackoverflow.com/questions/6510006/add-a-new-asset-path-in-rails-3-1
    config.assets.paths << Rails.root.join('app','assets','fonts')

    config.middleware.insert 0, 'Rack::Cache', {
      :verbose     => true,
      :metastore   => URI.encode("file:#{Rails.root}/tmp/dragonfly/cache/meta"),
      :entitystore => URI.encode("file:#{Rails.root}/tmp/dragonfly/cache/body")
    } # unless Rails.env.production?  ## uncomment this 'unless' in Rails 3.1,
                                      ## because it already inserts Rack::Cache in production

    config.middleware.insert_after 'Rack::Cache', 'Dragonfly::Middleware', :images

    config.action_mailer.default_url_options = { :host => CONFIG[:email][:host] }
    config.action_mailer.asset_host = 'http://' + CONFIG[:email][:host]
  end
end

宝石文件:

source 'http://rubygems.org'

gem 'rails', '3.2.13'   
gem 'mysql2'
gem 'dragonfly', '>= 0.9.14'
gem 'rack-cache', :require => 'rack/cache'
gem 'will_paginate'
gem 'dynamic_form'
gem 'amazon_product' # for looking up Amazon ASIN codes of books
gem 'geoip'
gem 'mobile-fu'
gem 'airbrake'
gem 'newrelic_rpm'
gem 'bartt-ssl_requirement', '~>1.4.0', :require => 'ssl_requirement'
gem 'dalli' # memcache for api_cache
gem 'api_cache'
gem 'daemons'
gem 'delayed_job_active_record'
gem 'attr_encrypted'
gem 'rest-client'
gem 'json', '>= 1.7.7'
gem 'carrierwave' # simplify file uploads
gem 'net-scp'

# Gems used only for assets and not required
# in production environments by default.
group :assets do
  gem 'therubyracer'
  gem 'sass-rails',   '~> 3.2.3'
  gem 'compass', '~> 0.12.alpha'
  gem 'uglifier', '>= 1.0.3'
  gem 'jquery-fileupload-rails'
end

gem 'jquery-rails'
gem 'api_bee', :git => 'git://github.com/ismasan/ApiBee.git', :ref => '3cff959fea5963cf46b3d5730d68927cebcc59a8'
gem 'httparty', '>= 0.10.2'
gem 'twitter'

# Auth providers
gem 'omniauth-facebook'
gem 'omniauth-twitter'
gem 'omniauth-google-oauth2'
gem 'omniauth-identity'
gem 'omniauth-readmill'
gem 'bcrypt-ruby', "~> 3.0.0" # required for omniauth-identity
gem 'mail_view'

# To use ActiveModel has_secure_password
# gem 'bcrypt-ruby', '~> 3.0.0'

# Deploy with Capistrano
group :development do
  gem 'capistrano'
  gem 'capistrano-ext'
  gem 'capistrano_colors'
  gem 'rvm-capistrano'

  # requirement for Hoof, Linux equivalent of Pow
  gem 'unicorn'
end

group :test, :development do  
  gem 'rspec-rails'
  gem 'pry'
  gem 'pry-rails'
end

group :test do
  gem 'factory_girl_rails'
  gem 'capybara'
  gem 'cucumber-rails'
  gem 'database_cleaner'
  gem 'launchy'
  gem 'ruby-debug19'
  # Pretty printed test output
  gem 'shoulda-matchers'
  gem 'simplecov', :require => false
  gem 'email_spec'
  gem 'show_me_the_cookies'
  gem 'vcr'
  gem 'webmock', '1.6'
end

这可能不会entirely回答你的问题,但我相信这是一个足够好的开始。正如您将看到的,准确的答案将取决于各个应用程序、gem 版本等。

所以。对于与资产相关的工作,如您所知,Rails 使用一个名为 Sprockets 的库,我相信在较新版本的 Rails 中,它作为 Railtie 连接到 Rails 中。它初始化一个 Sprockets“环境”,可以执行一些操作,例如查看资产清单、加载这些文件、压缩它们、为编译后的资产提供合理的名称等。

默认情况下,Sprockets::Environment将其活动记录到STDERR日志级别为FATAL,这在这些情况下不是很有用。幸运的是,Sprockets::Environment (as of 2.2.2)有一个可写的记录器属性,您可以使用初始化程序通过 Rails 修补该属性。


所以,这就是我的建议,首先:

In config/initializers,创建一个文件,类似asset_logging.rb。在其中放入:

Rails.application.config.assets.logger = Logger.new($stdout)

这会用一个记录器覆盖默认记录器,该记录器会向您输出更多信息STDOUT。设置完成后,运行资产预编译任务:

rake RAILS_ENV=production assets:precompile

你应该看到slightly更有趣的输出,例如:

...
Compiled jquery.ui.core.js  (0ms)  (pid 66524)
Compiled jquery.ui.widget.js  (0ms)  (pid 66524)
Compiled jquery.ui.accordion.js  (10ms)  (pid 66524)
...

但最终,最终的答案将取决于:

  • 您想要记录这些资产的“深度”
  • 您使用的 Rails、Sprockets 等的具体版本
  • 以及你一路上发现的东西

正如您已经了解到的,在 Rake 任务级别甚至在 Rails 级别进行日志探索并不能提供太多信息。即使让链轮本身变得冗长(见上文)也不会告诉你太多信息。

如果您想比 Sprockets 更深入,您可以对 Sprockets 尽职尽责地链接在一起的各种引擎和处理器进行修补,以使资产管道正常工作。例如,您可以研究这些组件的日志记录功能:

  • Sass::Engine(将 SASS 转换为 CSS)
  • Uglifier(JavaScript 压缩器包装器)
  • ExecJS(在 Ruby 中运行 JavaScript;Sprockets 和 Uglifier 的依赖项)
  • therubyracer(V8 嵌入 Ruby 中;由ExecJS)
  • etc.

但我将把所有这些作为“读者的练习”。如果有灵丹妙药,我当然想知道!

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何调试速度慢得难以忍受的 Rails 资源预编译 的相关文章

  • 如何找出正在使用哪个(版本的)函数?

    问题 如何找出正在调用的函数的版本 例如 如果我使用unique在 data frame 上 我假设我正在使用unique data frame 然而 没有unique raster函数 虽然有一个raster unique 但如果我使用
  • 如何在使用代理服务器访问 Internet 的 Windows 计算机上安装 Rails?

    我是 ruby 方式的忠实粉丝 然而今天它妨碍了我 安装rails的事实上的方法 我在WinXP机器上以域用户身份运行 是 下载并安装 ruby 一键安装程序 type gt gem install rails在命令提示符下 步骤 2 失败
  • Android Studio断点交叉解释

    我正在 Android Studio 中使用断点调试我的 Android 项目 我注意到有时我的断点中有一个十字并且不会暂停执行 在 intellij 网站上 这被解释为 显示何时在注释或不可执行的行上设置断点 表明不会命中此类断点 谁能告
  • 当 SQL 包含变量时在 pgAdmin 中调试 SQL

    在 SQL Server 中 我可以从应用程序中复制 sql 代码并将其粘贴到 SSMS 中 声明并分配 sql 中存在的变量并运行 是的 很棒的调试场景 例如 请注意 我很生疏 语法可能不正确 declare x as varchar 1
  • jruby-openssl 中已初始化常量

    当在 Torquebox 上运行我的 Rails 应用程序时 我得到了很多 already initialized constant 警告源自gems jruby openssl 0 8 2 lib shared jruby openssl
  • 追踪 int[] 的分配情况

    当查看我的remote通过 JMX 在 JVisualVM 中的应用程序中 我看到空闲时内存使用呈锯齿状 进行堆转储并使用 JVisualVM 进行分析 我发现很大一部分内存位于几个大的内存中int 没有引用的数组 通过比较堆转储 我可以看
  • before_filter set_locale 除了控制器

    My routes rb MyApp Application routes draw do scope locale do all resources here end namespace blog do resources posts o
  • 在 64 位计算机上捕获的 32 位进程的调试转储

    我最近收到一位客户发来的 64 位故障转储 我们的进程都是32位的 但是客户的机器运行的是x64 Server 2008 Visual Studio 2008 和 2010 Express 告诉我必须使用 64 位版本MSVSMON EXE
  • 设计没有路由与指定删除的链接中的 [GET]“/users/sign_out”匹配

    因此 我四处寻找解决此问题的方法 大多数人似乎都说了同样的话 但对解决我的问题没有多大作用 我已在链接中指定了删除方法 但路由错误表明这是一个 GET 请求 知道为什么下面的链接最终会覆盖 忽略方法声明吗 Routes devise for
  • 如何在Eclipse调试器中查看崩溃原因

    按照这个 Android 教程 http developer android com resources tutorials hello world html http developer android com resources tut
  • Bundler 找不到 gem“rack”的兼容版本:

    我是 Ruby 新手 但实际上如果我不想安装 Redmine 我就不需要它 我正在按照以下说明进行操作http www redmine org projects redmine wiki HowTo install Redmine on C
  • 是否仍然可以在 Rails 4 中使用测试单元?

    从 Rails 3 2 升级到 Rails 4 后 我的应用程序可以运行 但我用测试单元编写的测试是一场灾难 据传 Minitest 与测试单元 兼容 然而 如果我尝试使用 现在捆绑的 Minitest 就会发现有很多差异 从断言 语句名称
  • 如何在 PHP 中获取有用的错误消息?

    我经常尝试运行 PHP 脚本 但只是得到一个空白屏幕 无错误信息 只是一个空屏幕 原因可能是一个简单的语法错误 错误的括号 缺少分号 或者函数调用失败 或者完全是其他原因 很难找出哪里出了问题 我最终注释掉了代码 在各处输入 echo 语句
  • 如何向 ActiveRecord 集合添加方法?

    我想为特定模型的所有集合添加一个方法 假设我想添加方法my complicated averaging method到 WeatherData 集合 WeatherData all limit 3 my complicated averag
  • 在 Rails 中使用 config.assets.precompile 将资源包含在子目录中

    我有一个在 Heroku 上运行的 Rails 3 1 3 应用程序 通过 S3 进行资产托管asset sync 包含在我的app assets css目录是一个包含两个文件的子目录 main css scss and categorie
  • 使用 Rails3-autocomplete gem 时出现“自动完成方法不存在”错误

    在我的rails应用程序中 我尝试使用rails3 jquery autocomplete gem 我在 Gemfile 中包含了以下行 gem Rails3 jquery autocomplete 并提供捆绑安装及其在 gems 中列出
  • 后端验证轨

    如何验证文本列不包含网站 示例可以是 www google com google com http gooogle com http www google com https www google com https google com
  • 哈米尔评论结束

    我是哈米尔新手 这让我很困惑 我不喜欢删除可以注释掉的代码 但我不知道如何在 haml 中正确结束注释 这是一个代码片段 field f label member id br f text field member id field f l
  • 安装适用于 Windows 7 的 Ruby on Rails(最新)

    我是一名设计师 而不是一名编码员 并且在首次安装时遇到了问题 我下载了 Rails 1 8 6 和 Instant Rails 我打开控制台并尝试更新 gem 那里没有任何作用 我想我会删除所有内容并重新开始 因为我确信我现在破坏了某些东西
  • 如何从我的网站在 Facebook 上发布新闻源

    我有一个网站 允许用户通过 RPX 系统使用 Facebook 登录 ID 登录 当用户在我的网站上发表评论时 我希望它也能自动在他们的 Facebook 墙上发布评论 我如何使用 Rails 来做到这一点 我已经学习 facebooker

随机推荐