Rails 3 - Speed up Console Loading Time

Solution 1:

I finally found my startup bottlenecks using Benchmark. In particular, navigate to the bundler gem and in lib/bundler/runtime.rb, find the line that does Kernel.require and wrap it like this:

puts Benchmark.measure("require #{file}") {
  Kernel.require file
}.format("%n: %t %r")

You may have to add require 'benchmark' somewhere in your app, like in config/boot.rb. That will show you how long it takes to require each gem. I can't guarantee your results will match mine, but I had a few gems that were taking over a second to load compared with sub-millisecond for most. A few were gems that I didn't need for developing but I did need for some tasks in the development environment, e.g. capistrano, shoulda. I benchmarked other areas of startup (initializers, etc), but couldn't find any significant bottlenecks.

I haven't yet figured out a clean way to configure the app to only load those for tasks where they are really needed. Possibly, I could create an environment called :speedy and use RAILS_ENV=speedy rails s/c for startup when I know I don't need those gems. Then in Gemfile, I could use group :speedy to exclude those gems in certain cases.

All that said, the biggest startup annoyance for me is having to load the entire environment to run a rake task. I could probably exclude most gems for that, but Gemfile would start to get messy so I don't know if it's worth it.

Solution 2:

Slightly adapted form that is copy-pastable, wraps all requires, and provides sortable output:

# Add this to the top of boot.rb
require 'benchmark'
def require(file)
  puts Benchmark.measure("") {
    super
  }.format("%t require #{file}")
end

Then you can execute no-op to see them:

rails runner 1

Or sort them and show the top 50:

rails runner 1 | sort -nr | head -n 50

Solution 3:

You can speed it up by adding :require => nil to the slow Gemfile entries and require them manually. e.g.

gem 'jammit', :require => nil

I also addressed this issue in a meetup i've had. This seems to be a bug in ruby 1.9.2 (see comments of this patch: https://gist.github.com/1008945)

You can fix it by patching your 1.9.2 by the gist i just linked or upgrading to 1.9.2-head or 1.9.3-head.

Solution 4:

This is definitely about cleaning up your code and identifying bottlenecks, but once you've made those savings it's worth looking at something like Zeus to speed up your dev times.

gem install zeus

https://github.com/burke/zeus (docs)

It's not without bugs and does sometimes require a reboot but I am still seeing an overall increase in development times by fast server and console reboots after small code changes.

Solution 5:

Very old question & answers, but it's still a useful one...

Somehow have an error with jqr answer, which seems related to autoload (rails 5.2...).

-e:1:in `<main>'                                                                                                                                                                                           
0.002514 require i18n/config                                                                                                                                                                               
.../vendor/bundle-dev/ruby/2.7.0/gems/i18n-1.8.7/lib/i18n.rb:19:in `<module:I18n>': uninitialized constant I18n::Config                                           
Did you mean?  RbConfig (NameError)                                                 

Fixed with this :

# Add this to the top of boot.rb
require 'benchmark'
def require(file)
  mod = nil
  puts Benchmark.measure("") {
    mod = super
  }.format("%t require #{file}")
  mod
end