Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Removing Cache Busting in Rails Production

When i deploy a rails application in production mode, it appends a date-time string as a query param to the end of all the static asset urls. This is to prevent browsers using old-out of date cahed copies of the assets after I redeploy the application.

Is there a way to make rails use the old time stamps for the assets that have not changed (and only the ones that have not changed) since the last deployment. I want to do this to prevent users having to redownload those assets that have not changed.

like image 549
Laurie Young Avatar asked Oct 08 '08 14:10

Laurie Young


People also ask

Is cache busting necessary?

Cache busting is useful because it allows your visitors to receive the most recently updated files without having to perform a hard refresh or clear their browser cache.

How do I flush Rails cache?

clear in the Rails console to clear the cache. Unfortunately there is no way (yet) to do it from the command line. We can add a rake task that will do this for us. Then we can execute ./bin/rake cache:clear and clear the Rails cache from the command line.

What does cache busting mean?

Cache busting is a way to prevent browsers from caching your ad content. Cache busting adds a random string to your ad tag each time the tag fires — typically a random number. Because the tag has a different number each time, the browser sends a new request each time.

Where does Rails store cache?

This cache store uses Danga's memcached server to provide a centralized cache for your application. Rails uses the bundled dalli gem by default. This is currently the most popular cache store for production websites. It can be used to provide a single, shared cache cluster with very high performance and redundancy.


1 Answers

Capistrano, by default, touches every file it considers an 'asset'. As you said, this means after every deploy rails thinks every asset has changed and browsers wil download a newer version every time.

You can disable this in Capistrano with the following setting

set :normalize_asset_timestamps, false

If you are using SVN then the modified dates for your files should reflect the dates they were last modified in your repository, so that should be perfect.

If you are using Apache, you can add something like this to really making caching work for you. This helps by telling the browser to rely on the "Cache Control" directives meaning if it knows the asset is cached, it won't even bother requesting it.

#Etags should be based on the file parameters only (default includes INode)
FileETag MTime Size  

#Rewrite stuff
RewriteEngine On  

#This sets the environment variable (is_versioned) when the URL query string
#looks like ?874353948543  or any string of digits
RewriteCond %{QUERY_STRING} ^[0-9]+$
RewriteRule ^(.*)$ $1 [env=is_versioned:true]  

<Directory /deployed-rails-app/public/ >
    Options -Indexes FollowSymLinks -MultiViews
    AllowOverride None
    Order allow,deny
    allow from all  

    #For files, force the browser to rely on cache-control directives and 
    #Rails asset timestamps by removing Etags and Last-Modified dates  

    #For all assets that aren't stamped by rails, cache them for ~ 3 hours
    Header set "Cache-Control" "max-age=10000"
    Header unset Etag
    Header unset "Last-Modified"  

    #For all assets that ARE stamped by rails, cache them for 30 days
    Header set "Cache-Control" "max-age=2592000" env=is_versioned

</Directory>

I've set my production server up this way and now return visitors only perform one request (Get /) which returns the dynamic content and all the assets (~ 40 - 50) are cached.

like image 158
Daniel Beardsley Avatar answered Nov 02 '22 11:11

Daniel Beardsley