Read more

Using rack-mini-profiler (with Unpoly)

Niklas Hä.
April 16, 2024Software engineer at makandra GmbH

Debugging performance issues in your Rails app can be a tough challenge.

Illustration money motivation

Opscomplete powered by makandra brand

Save money by migrating from AWS to our fully managed hosting in Germany.

  • Trusted by over 100 customers
  • Ready to use with Ruby, Node.js, PHP
  • Proactive management by operations experts
Read more Show archive.org snapshot

To get more detailed insights consider using the rack-mini-profiler Show archive.org snapshot gem.

Setup with Unpoly

Add the following gems:

group :development do
  gem 'memory_profiler'
  gem 'rack-mini-profiler'
  gem 'stackprof'
end

Unpoly will interfere with the rack-mini-profiler widget, but configuring the following works okayish:

// rack-mini-profiler + unpoly
if (process.env.NODE_ENV === 'development') {
  // disable unpoly for links in the profiler
  up.link.config.noFollowSelectors.push('.profiler-results a')

  document.addEventListener('up:link:follow', () => {
    if (window.MiniProfiler !== undefined) {
      window.MiniProfiler.pageTransition()
    }
  })
}
# config/initializers/rack_mini_profiler.rb
if Rails.env.development?
  Rails.application.config.to_prepare do
    Rack::MiniProfiler.config.position = 'top-right' # positon widget top-right
    Rack::MiniProfiler.config.skip_paths = [ # ignore most asset requests
      %r(/system.*),
      %r(/assets.*),
    ]
    Rack::MiniProfiler.config.html_container = 'html' # avoid unpoly replacements
  end
end

SQL

Rack-Mini-Profiler will give you a lot of detailed information about SQL queries happening on your page. You will spot N+1, unecessary and slow queries this way.

Flamegraphs

If you're wondering where most of your time is spent, consider generating a flamegraph Show archive.org snapshot .There are a lot of different config options, but appending ?pp=async-flamegraph&flamegraph_ignore_gc=true to your URL will generate a readable flamegraph for this request, without garbage collector gaps. You can then open the flamegraph by clicking the widget and following the "flamegraph" link at the bottom of the request's page. Search for long method calls in the graph and consider fixing those.

Caution

The gem also allows displaying the flamegraph directly by appending ?pp=flamegraph&flamegraph_ignore_gc=true. But if the controller doesn't explicitly call the render method, the view rendering won't be part of the flamegraph and you will miss slow queries there. Use with caution.

Some potential wins

  • If you have slow ActiveRecord queries, consider speeding those up.
  • If you have slow views (Haml/Partials can be slow), consider caching them.
  • Remove code & sql-queries that are not needed to render the page.
  • Calling to_a blindly on scopes will always force to load records, this is almost always unnecessary and slow

Caveats

Your development environment is configured differently than your production environment. The closer your envs match when profiling, the more reliable are your profiler results.

Don't get lost on optimizations on pages nobody cares about. Find quick wins in the most visited and important sites, your customer will tell you which pages those are.

Warning

Don't write performance optimized code by default. Monitor performance in production, spot an issue, reproduce locally, fix it and then verify your fixes in production.

Niklas Hä.
April 16, 2024Software engineer at makandra GmbH
Posted by Niklas Hä. to makandra dev (2024-04-16 13:38)