I’ve been working on a rails app which has got quite a number of pages that share the same two css files and 3 javascript files. However, every time I visited any page of the app, all of javascripts and css files were being loaded from the server. Not good – site was very slow. Mucking around with ‘about:cache’ command in Firefox revealed that the css and javascript files had expiry dates set in the past – ie, no caching of them at all. Also, all the links to sylesheets and javascript files generated by rails had ?[some long number] after them. Some research on the web revealed that this is a new rails feature for caching – the long number is a timestamp for when the asset was last modified.

Okay, so why were these assets not being cached? A quick check with wget –save-headers revealed that the web server was sending a nocache directive to the browser. This seems to be the default setup for webrick and also for my shared apache hosting on railsplayground. Considering the new rails asset management system with the ?[last modified timestamp] in the URLs, nocache seems wrong. The browser should never expire the cache since rails will handle cache invalidation by updating the asset url with a new timestamp.

So, how can we implement no/very long cache expiry? In apache, you can use mod_expires or mod_headers to do this. My shared hosting does not support mod_expires, so I went for mod_headers in my .htaccess file.

Using mod_headers:

<FilesMatch "\.*$">
Header set Cache-Control "max-age=29030400"
</FilesMatch>

OR using mod_expires:

ExpiresActive On
ExpiresDefault "access plus 1 year"

Either of the the above will set up a cache expiry time of one year for all content (best you only do this for your rails app directories).

With a cache expiry time of one year in place, my rails apps run much much faster.