Ruby on Rails Application Performance Optimization Tutorial

22 Aug 2019
0 Comments
Ruby on Rails Application Performance Optimization Tutorial

You created a web application in Ruby on Rails, and it seems like it's business logic works correctly, the UI is user-friendly, and the design is very attractive. But, are you sure that it will really meet all the expectations of its users?

Application speed and performance are very important when it comes to project success. Users expect the application to load as quickly as possible. The standard page loading time is a maximum of 2 seconds.

Prerequisite:

  • For checking the precise speed of application pages run the application in production mode.

  • check the disable cache from browser console. This will completely disable the Google Chrome cache

Now, we will check the existing application speed by browsing through each page of the application and keep them noted in .xls or any other file for comparing the speed of the application after optimization completes.

There are several tools to measure the page loading time. For ease of use, I am using google chrome extension Page load time. Once page load time extension is added in the browser it will show the loading time of page as any web page is loaded on the right top corner of chrome browser.

 

WAYS TO IMPROVE APPLICATION PERFORMANCE:

  • Database Performance

i) N+1 queries:

It is difficult to spot N+1 problems which occur in rails. N+1 means one object was called and then a second object was called, creating a second query. This then compounds. So, you may be running 100 queries to get one result instead of running one query with 100 results.

Bullet gem is used to spot the N+1 queries in the application. You can check the bullet gem documentation for the usage of this gem.

To avoid the N+1 issue is through eager loading. This can be accomplished by using .includes on querying code.

# app/views/users/index.html.erb

<% @users.each do |user| %>

     <%= user.name %>

   <%= user.addresses.first.city %>

<% end %>

##above code will produce 101 queries if you have a database with 100 users.

Here's what it looks like when adding eager loading by adding the .includes:

# app/controllers/users_controller.rb
class UsersController < ApplicationController
    def index
        @ users = User.includes(:addresses).all
    end
...
...
end


## this should produce 2 queries on the same 100 customers.


ii) Add index on the N+1 queries:

Once you know where the issue is taking place, consider adding indexes to troubled tables. Searching an index on a table with 1,000 rows is 100 times faster than searching the same table without an index. When adding an index, it’s important to note that the table will lock so no inserts will occur while the index is being built.

class AddIndexForUser
    def change
        add_index :users, :users_id
    end
end
## example migration file to add index
  • Replace Http requests with local files

=> Don’t use cdn to load the plugin files. Most of the developer uses jquery and bootstrap cdns in hurry, that increases the page loading time that’s not the right way. The proper way is to store them on the local assets directory and use it in the application.

First of all, find out all the cdn’s added in the project directory(often found in application.html.erb) and remove them, then you can add a gem or local files for the plugin instead of adding cdn. This will reduce the page loading time.

 

  • Use Pagy for Pagination 

Pagination makes page loading faster and more memory efficient by slicing a large number of records into a few pages rather than one never-ending mess. But the two most commonly used gems to achieve this in Rails viz. i) Kaminari and ii) Will Paginate are both slow, inefficient, memory hogs.

Instead of using those gems use Pagy, a faster, much more memory-efficient gem designed with performance in mind. You can find steps to use this gem on the gem documentation page.




Leave a comment: