views:

648

answers:

5

I'm researching this for a project and I'm wondering what other people are doing to prevent stale CSS and JavaScript files from being served with each new release. I don't want to append a timestamp or something similar which may prevent caching on every request.

I'm working with the Spring 2.5 MVC framework and I'm already using the google api's to serve prototype and scriptaculous. I'm also considering using Amazon S3 and the new Cloudfront offering to minimize network latency.

+1  A: 

Use a conditional get request with an If-Modified-Since header

Andreas Grech
A: 

This is actually a very hard issue, and something that you can spend a while engineering the correct solution for.

I would recommend publishing your files using a timestamp and/or version built into the url, so instead of:

/media/js/my.js you end up with:

/media/js/v12/my.js or something similar.

You can automate the versioning/timestamping with any tool.

This has the added benefit of NOT breaking the site as you roll out new versions, and lets you do real side-by-side testing (unlike a rewrite rule that just strips the version and sends back the newest file).

One thing to watch out for with JS or CSS is when you include dependent urls inside of them (background images, etc) you need to make sure the JS/CSS timestamp/version changes if a resource inside does (as well as rewrite them, but that is possible with a very simple regex and a resource manifest).

No matter what you do make sure not to toss a ?vblah on the end, as you are basically throwing caching out the window when you do that (which is unfortunate, as it is by far the easiest way to handle this)

Todd Berman
+9  A: 

I add a parameter to the request with the revision number, something like:

<script type="text/javascript" src="/path/to/script.js?ver=456"></script>

The 'ver' parameter is updated automatically with each build (read from file, which the build updates). This makes sure the scripts are cached only for the current revision.

Eran Galperin
the best solution is the simpliest :) Thank you
Mike
A: 

If you get the "modified time" of the file as a timestamp it will be cached until the file is modified. Just use a helper function (or whatever it is called in other frameworks) to add script/css/image tags that get the timestamp from the file. On a unix like system (wich most survers are) you could simply touch the files to force the modified time to change if necessary.

Ruby on Rails uses this strategy in production mode (by default I beleave), and uses a normal timestamp in development mode (to be really sure something isn't cached).

Stein G. Strindhaug
+1  A: 

With regards to cached files, I have yet to run into any issues of bugs related to stale cached files by using the querystring method.

However, with regards to performance, and echoing Todd B's mention of revving by filename, please check out Steve Souders' work for more on the topic:

"Squid, a popular proxy, doesn’t cache resources with a querystring. This hurts performance when multiple users behind a proxy cache request the same file - rather than using the cached version everybody would have to send a request to the origin server."

"Proxy administrators can change the configuration to support caching resources with a querystring, when the caching headers indicate that is appropriate. But the default configuration is what web developers should expect to encounter most frequently."

http://www.stevesouders.com/blog/2008/08/23/revving-filenames-dont-use-querystring/

Geoff