Suffix

Rails 3.1 asset pipeline in production

Compress assets during Rake deploy.

The asset pipeline is probably one of the biggest additions in the upcoming 3.1 release of Ruby on Rails. It’s a framework to minify and compress JavaScript and CSS code. The asset pipeline pre-minifies and pre-compresses all your JavaScript code in a single file, the same goes for your stylesheets. This results in smaller files and fewer HTTP requests, meaning faster applications!

The asset pipeline is enabled by default but will look a little strange if you are migrating from an older version of Ruby on Rails. Let’s have a quick look.

Development

You should have seen the /app/assets directory in your new Rails 3.1 app, this is where all the magic happens. All JavaScript, CSS, and image files which would previously go to /public now go to /app/assets/javascripts, /app/assets/stylesheets, and the /app/assets/images folders. Point your browser to localhost:3000, inspect the source and you’ll see Rails concats all the JavaScript and CSS in two single files. Off course you can turn this off for debugging if you want.

Production

There are a few more steps involved to make this work in production. Wouldn’t it be nice to pre-compress the assets for production to save some precious processor time? Let’s compress the assets right after our Capistrano deployment:

after "deploy:update_code", "deploy:precompile_assets"
desc "Compile all the assets named in config.assets.precompile."
task :precompile_assets do
  raise "Rails environment not set" unless rails_env
  task = "assets:precompile"
  run "cd #{release_path} && bundle exec rake #{task} RAILS_ENV=#{rails_env}"
end

After deploying your code to production you should see a new /public/assets folder with your compressed files (an MD5 hash has been added to the filenames). The hash makes it possible for browsers to cache the files indefinitely. As long as the filename is the same there is no need to fetch the file again after it has been downloaded. Change your code and deploy again and you’ll see the hashes have changed.

So far so good but you may have noticed all the images referenced in the stylesheets are gone. Well, the image filenames now include the MD5 hash so the browser is looking for logo.png and doesn’t find anything. Instead, it should look for something like logo-d41d8cd98f00b204e9800998ecf8427e.png. Let’s make our CSS a bit more dynamic.

First rename all your /assets/stylesheets CSS files to something ERB will understand: e.g. default.css.erb. This allows us to use ERB in the stylesheets. Now change all the image references to:

<%= asset_path 'logo.png' %>

Deploy your application again and you should be good to go. All image references in your stylesheets have been replaced by their “hashed” version.

Read more