Web Dev - How to inform browsers to update their cache?
October 9, 2009 1:25 PM   Subscribe

I am developing a website that has a moderately-sized user base. I am going to be rolling out a new version of the page soon. In my testing, I have noticed that my browsers don't notice that there are new versions of some of the CSS files available on the servers, and renders the page with the old CSS files. This causes display glitches. How do I let browsers know that new CSS/Javascript files are available and to update it's cache?
posted by LoopyG to Computers & Internet (18 answers total) 3 users marked this as a favorite
 
One trick is to add a current timestamp to the end of the .js or .css files

file.js?11111111111
posted by bitdamaged at 1:43 PM on October 9, 2009 [1 favorite]


There's probably a "more correct" way to do this, but I would just rename my css and js files to be different than the existing ones.
posted by mattybonez at 1:44 PM on October 9, 2009


Best answer: Both of those above methods work, however if you've got hundreds of html pages pointing to one css file, changing the name of it isn't a great option.

You want to send an expires HTTP header (so it expires in the past) with the CSS file being served. The browser will then grab the most up to date version of the file instead of grabbing it from the cache.

http://www.onenaught.com/posts/17/web-site-performance-expires-header

That's how to do it in apache with your htaccess file. It's even simpler in IIS if you're on a windows server.

As soon as you've finished development, you just revert the expires header back to normal so people can use their cached version and speed up their browsing.
posted by derbs at 2:23 PM on October 9, 2009 [1 favorite]


Response by poster: Ahhh, I see. I have already set up expires headers to be one month. But when I am ready to make these changes live, I'll set that expire to be in the past, then after one month set them back to normal. Thanks for the advice derbs.
posted by LoopyG at 2:29 PM on October 9, 2009


My understanding is that already cached files can not be un-cached via an expires headers (I could however be wrong). The file is already downloaded and still valid so there's no reason to check the origin server for a new file (and receive new headers). You must change the query string/url to force a new get of existing files.
posted by bitdamaged at 2:52 PM on October 9, 2009


Best answer: Well, no - if you set the expire to be in the past when you ready to make the changes live, it'll be up to a month before users see it! You say you're rolling out a new version "soon", so set the expire in the past now.

Or, use the file naming trick, which gives you better control at the cost of some search-and-replace at roll-out time.
posted by nicwolff at 2:52 PM on October 9, 2009


Uh, my "well no" was in reference to LoopyG, who is mistaken, not bitdamaged, who is right.
posted by nicwolff at 2:53 PM on October 9, 2009


I thought a conditional request was made regardless of cache to see if a 304 Not Modified was returned (instead of the entire document)?
posted by cj_ at 3:01 PM on October 9, 2009


Response by poster: Oh? I thought that browsers queried the server on whether to update their cache. I have a common header file throughout my pages, so changing the filename of the css/js file by appending a ?VER where VER is some version number is not a problem. I will go for that solution as well. Thanks.
posted by LoopyG at 3:01 PM on October 9, 2009


Yeah I am pretty sure that's the case. tcpdump'ed a reload of this page and my browser sends:

If-Modified-Since: Thu, 22 Mar 2007 06:04:47 GMT

in the request header, and the server responds with:

304 Not Modified.

Maybe not all browsers behave this way, though, I'm not sure.
posted by cj_ at 3:08 PM on October 9, 2009


Yeah i'm pretty sure that if you're navigating directly to a website (ie. not using the back or forward buttons), then the browser will issue a if-modified-since request regardless of the original expires value on the file in the cache. If the CSS file has a expires -1 header then the server response will indicate that the css file has been modified and the browser will grab the latest css file.
posted by derbs at 3:13 PM on October 9, 2009


Personally, i'd follow nicwolff's advice and set the expires header of the css file to -1 now. I know IE will still check the if-modified-since response even if you do set it like that (not sure about firefox or safari).

Plus unless your CSS file is hundreds of K or your users are on dial up, the css file will only take a fraction of a second to download in browsers that don't support if-modified-since.
posted by derbs at 3:30 PM on October 9, 2009


cj_ Try navigating directly to a site you've cached and watch the dumps - I'm doing this in Firefox with Live HTTP headers.

Hitting reload does force a check. Navigating directly does not (not through back/foward but going directly to the url).
posted by bitdamaged at 3:42 PM on October 9, 2009


bitdamaged: My test was with Safari 4. I just tried with Firefox 3.5 and it didn't request cached files at all without force reload as you say. I guess Firefox is more aggressive about caching.
posted by cj_ at 3:48 PM on October 9, 2009


I was under the impression that the cache behavior in regard to If-Modified also varies by whether or not the file was requested in this browser session. When developing and testing, I end up using force reload all the time, but for our normal users, things tend to work just find the next morning.

Of course, none of this seems to apply when we use @import statements in a css file. That seriously confuses me.
posted by advicepig at 4:29 PM on October 9, 2009


You should be versioning your static objects by name and setting far-future cache times, for performance reasons alone - this avoids even the overhead of the if-modified-since queries, which still take up time.
posted by TravellingDen at 7:24 PM on October 9, 2009


"I thought a conditional request was made regardless of cache to see if a 304 Not Modified was returned (instead of the entire document)?"

Nope - that's just a nicety. If you set expires headers properly, the browser won't even bother asking if the file has been modified - it's already been told the object is good for a certain period of time.
posted by TravellingDen at 7:26 PM on October 9, 2009


I can't speak to performance, but when this is essential I've always used versioning numbers as TravellingDen suggests.
posted by maxwelton at 12:32 AM on October 10, 2009


« Older Looking for a simple and ergonomic men's watch   |   Are meat and leather production correlated? Newer »
This thread is closed to new comments.