Although the development of applications is fast in Rails, the applications themselves are often a bit slow. The elegant framework increases the productivity of the programmer but reduces the performance of the application. The DRY principle is great to prevent code repetition, but it is less optimal to increase speed: it is of course much faster to render a simple HTML page instead of a complex page with dozens of deeply nested partials. Sometimes it is not easy to find the right trade-off between code elegance and raw speed. Luckily there are some easy optimizations we can make. It is possible to optimize each of the server in the application by improving the hardware and the caching options: SQL server, app server and web server. And it is possible to optimize their interactions by minimizing the number of requests. The most important and effective tool to increase performance is the classic trade-off between static and dynamic pages: caching (with suitable timed-based expiration). Caching is the fundamental principle to increase the speed of applications. Pre-calculated and cached values don’t need to be calculated in a costly way. Here is what you can do to increase the performance of your Rails application:
Minimize HTTP Requests
– combine CSS and JS files with the :cache option
– use CSS Sprites
– avoid HTTP 302 redirects
– replace full HTTP requests by XHR requests (i.e. Ajax calls)
Minimize Database Requests
– Optimize queries, eager loading of associations with :include and JOIN
– use Rails caching: action, page and fragment caching, Memcache is an option
– use caching with timed-based expiration for dynamic content
– group operations in a transaction
– use counter cache columns
– denormalize (e.g. comma-separated list of ids in single fields to cache queries)
– precalculate data through rake tasks
– use a Sphinx search server for searching
Minimize Response Size
– SELECT only the needed columns
– LIMIT the number of return datasets (pagination)
Minimize Framework Activity
– use direct links instead of link_to or url_for to avoid routing
– avoid dynamic finders like Model.find_by_*.
Minimize Database Activity
– use secondary indices for your database (Rails won’t do this for you)
– increase SQL-Server query cache