Speeding Up Your Rails Web Site
Optimizing web sites is complex, but necessary topic to understand as web developers to achieve faster web applications. There are many well known resources that have identified best practices to improve website performance. Many web frameworks have made these tasks easier by abstracting the complexity away, but not all of them are well documented, some features are hidden and some are not possible at the framework level. These entries will focus on different topics and attempt to identify how to perform these optimizations, or how they are automatically done, within the Rails framework.
Make Fewer HTTP Requests
In HTTP 1.0 servers would typically close a TCP connection after each request (in HTTP 1.1 persistent connections are a solution). The overhead of opening and closing connections as well as limitations of maximum parallel connections per server make web page loading slower.
To avoid these issues, as you may have guessed, typical solutions pack multiple requests into a single request.
Combining Javascript and CSS
Rails can automatically join Javascript and CSS files together. The asset pipeline has the concept of manifest files to declare the files you want to include together (typically application.css
and application.js
). In production all the javascript and css files will be joined into a single file.
// This is a manifest file that'll be compiled into including all the files listed below.
// Add new JavaScript/Coffee code in separate files in this directory and they'll automatically
// be included in the compiled file accessible from http://example.com/assets/application.js
// It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the
// the compiled file.
//
//= require jquery_ujs
//= require_tree .
//= require contacts
Then you can include links to the manifest files in your layouts:
<%= stylesheet_link_tag "application", :media => "all" %>
<%= javascript_include_tag "application" %>
Combining Images (Sprites and CSS)
As for images, there is no default way in Rails that joins image requests together, aka spriting. To do this you need to use a library such as Compass. Organize a set of images in a folder and the images will be sprited together. Helpers exist to easily allow you to reference a single image within the sprite map. To include the sprite folder in Compass you would declare the following:
1 @import "logos/*.png";
2 @include all-logos-sprites;
Once you have included the sprites, you can reference dynamic namespaced class names, like logos-foursquare-powered
.
<%= sprite_link "logos-foursquare-powered", "http://foursquare.com", :target => '_blank' %>
Inline images
Another common way to reduce requests is to encode an image in Base64 and include it in CSS for example. The way to achieve this in Rails is to leverage the sass-rails gem and use the helper inline-image
.
1 background-image: inline-image('so-informed.png');
- Is this better in a sprite?
- Is this image too large after it is Base64 encoded?
- Is this just on a page that needs to load extremely fast?