Rails Asset Cache
As a follow up to our article on Minifying Your Rails Javascript, let's take a look at a new feature in Rails 2.0 that makes packaging your assets into a single file much easier.
Enabling Cache
We use asset helpers such as javascript_include_tag and
stylesheet_link_tag in our layouts to include
external Javascript and CSS files. One benefit of using these helpers is
the ability to cache these resources. Asset cache is turned on when
the perform_caching configuration option is set to
true.
Rails applications default to having caching disabled during development,
and enabled in production. We can change this in
config/environments/development.rb to test out caching
during development.
config.action_controller.perform_caching = true
Caching Assets
We enable asset caching in our applications using the :cache
option in our helpers. We can cache Javascript files by doing the following:
<%= javascript_include_tag "prototype", "application", "effects", :cache => "cache/all" %>
When caching is disabled, Rails will generate the normal references to these resources.
<script src="/javascripts/prototype.js?1197321216" type="text/javascript"></script> <script src="/javascripts/application.js?1197321216" type="text/javascript"></script> <script src="/javascripts/effects.js?1197321216" type="text/javascript"></script>
However when caching is enabled, Rails will generate a single external Javascript file in the location we specified. It will then reference this file instead of the original source files.
<script src="/javascripts/cache/all.js" type="text/javascript"></script>
As you can see in the above example, we're going to store our asset cache
in subdirectories named cache/. This makes it easier to
clear out the cache later on. Caching external CSS files works similar
to the Javascript example:
<%= stylesheet_link_tag "typography", "layout", "color", :cache => "cache/all" %>
Clearing Cache
Rails comes with some useful built-in tasks for clearing out temporary
files under the tmp: rake namespace. Rails
does not come with a built-in task for clearing out the asset
cache. We'll add this ourselves by adding a new rake task named
rake tmp:assets:clear. Create a new file in your Rails
application named at lib/tasks/tmp.rake, and add the
following code.
namespace :tmp do namespace :assets do desc "Clears javascripts/cache and stylesheets/cache" task :clear => :environment do FileUtils.rm(Dir['public/javascripts/cache/[^.]*']) FileUtils.rm(Dir['public/stylesheets/cache/[^.]*']) end end end
The custom tmp:assets:clear task we added removes
all files from both the javascripts/cache/ and
stylesheets/cache/ directories. Let's give it a whirl:
$> rake tmp:assets:clear
Wrap Up
Using asset cache can significantly reduce the number of requests sent to the server for external CSS and Javascript files. Along with a good gzip strategy, this is an essential feature when working with large multi-file Javascript libraries.
For additional performance increases using asset helpers, check out Chad Fowler's write-up of Distributed Asset Hosts.

