FireFox 3 and Static File Caching Problems
FireFox 3.0 apparently is much more aggressive in caching content than previous versions of FireFox. While this is good for performance in many situations I've noticed that this is seriously becoming a problem in some of my applications where support files like scripts and CSS files get updated and FireFox doesn't recognize those changes. The problem appears to be that FireFox is not sending the required 304 request to check for last-modified headers that are typically used for static files.
The latest example is my (ancient) Message Board site which I recently updated by reducing the HTML and externalizing most of the inline styling into an external CSS file that previously existed. Today I'm waking up to 10 messages from visitors that the the formatting of the message board is completely mangled. Apparently the CSS file changes are not being picked up by FireFox 3.0 and so users see the new dynamic message board pages, rendered against the old CSS styles cached in the browser. Thankfully I did this over the weekend and so the cacophony of disgruntled visitors was only minor.
The updated CSS file is there on the server. IE, Opera and Safari and even FF 2 all work fine - only FF3 fails to refresh the CSS for clients because apparently it's not detecting the last-modified date for the static resource. Even pressing Refresh doesn't fix this and even FireFox's 'hard' Shift-Refresh doesn't do the trick if the CSS is already cached.
Part of the problem here is that the app is frames based. Shift-Refresh should in theory force a refresh of all resources (and it does usually), but in the case of this frames based layout it doesn't. The only way to force the CSS to refresh that I found is to Ctrl-Click one of the links and force into a new frame, then force a Shift-Refresh in the new window. Intuitive, eh? Oh, or you can clear the browser cache! Yeah - that's what I tell 'em! <g>
But it's not only this CSS that suffers. I've also had issues with AJAX related static JavaScript files served from the server that also didn't work with the same caching issues. This is even more insidious because you can't see the problem except that potentially your app will fail now because the application's client application data is not up to date.
Again only a Shift-Refresh usually solves this problem. While this is fairly painless to do in the dev environment (it's become a habit already to Ctrl-Click) this is a big problem in production environments since you certainly don't want to tell your visitors to 'just Ctl-Click and things will be cool'.
It appears that the problem is vaguely related to this post:
With Firefox 1 and 2, “Cache-control: no-cache” accomplished this goal. I’ve spend the last several hours trying to figure out how to prevent Firefox 3 from caching my pages, with no luck. It completely ignores “Cache-control: no-store, no-cache, must-revalidate” and every combination of values for the “Expired:” header that I can think of, in blatant violation of RFC 2616 (14.9 and 14.21).
This post also mentions how you can modify your cache settings. While this works this is hardly a solution for end users.
Last-Modified Headers not working properly in FF3
The issue described in the post is in regards to caching, which is a little different actually than what I'm experiencing here, which has to do with the last-modified header that static files use. Web Servers serve static files (like CSS and scripts) from disk and they tend to serve this data with a last-modified header which the browser is supposed to respect. When requesting data again for a page that when originally loaded the browser is supposed to fire a 304 request to see if the content has changed.
Here's what the 304 response looks like in Internet Explorer with Fiddler enabled. IE fires the hit to the CSS file every time as a 304 request which looks like this:
GET /wwThreads/wwthreads.css HTTP/1.1
Accept: */*
Referer: http://www.west-wind.com/wwThreads/head.htm
Accept-Language: en-us
User-Agent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.0; Trident/4.0; SLCC1; .NET CLR 2.0.50727; Media Center PC 5.0; FDM; .NET CLR 3.5.21022; .NET CLR 3.5.30729; .NET CLR 3.0.30618; .NET CLR 1.1.4322)
UA-CPU: x86
Accept-Encoding: gzip, deflate
If-Modified-Since: Sun, 31 Aug 2008 09:37:26 GMT
If-None-Match: "20d7b72d4dbc91:0"
Connection: Keep-Alive
Host: www.west-wind.com
HTTP/1.1 304 Not Modified
Last-Modified: Sun, 31 Aug 2008 09:37:26 GMT
ETag: "20d7b72d4dbc91:0"
Accept-Ranges: bytes
Server: Microsoft-IIS/7.0
X-Powered-By: ASP.NET
Date: Sun, 31 Aug 2008 20:04:11 GMT
If the content were modified the server would respond with a full 200 HTTP response. So if I go in and modify my CSS file and hit the page again, IE will properly detect the change.
FireFox however, doesn't appear to fire the 304 at all. I've hooked up Firebug and the CSS files don't show up at all. Not trusting the FireBug network tracing I also hooked up FireFox to Fiddler and lo and behold it too shows that FireFox is not firing the 304's to check for updated files. When loading pages - even with Ctl-Clicking - I don't see the CSS files loaded which explains why the pages render all mangled. In my frames page even browser Refresh or even a Shift-Refresh doesn't cause the frames to reload their content or fire 304s to check for updates - all the static content is simply not accessed at all.
For example, if I start up FireFox fresh and navigate to my site and hit one link here's what Fiddler shows:
Notice there are no other requests to any support resources - images, CSS etc. No checks for 304's. Here's that same trace with Internet Explorer:
:
and you'll notice all the 304 hits to verify resources. Now using Shift-Refresh in Firefox will force FireFox to refresh all those links explicitly and load them, but this isn't the expected behavior. The whole point of last-modified and 304s is to be able to detect changes to static resources and apparently FireFox doesn't play along here.
Frames
Ok, frames are so passé but as I mentioned the app I'm actually dealing with uses frames and the problem there is that a Shift-Refresh on the parent frame isn't enough to force the individual frames to refresh. In fact, I'm not really sure how to force FireFox to refresh an individual frame. The only way I've been able to do this is to load one of the frames by shift clicking into a separate window and then doing a shift-Refresh to force the stylesheet to reload. After that all's well because that updates the cache globally.
Refresh should be Refresh
What's worse though is that in FireFox 3's default configuration even clicking the Refresh button will not force 304s. Apparently the Refresh button behavior has been changed to only re-run the last request EXACTLY in the same mode it was run. So if you did a Shift-Refresh on the last hit, it will repeat that behavior. If you did a plain link click that will replay exactly and so on. There's no longer an explicit reloading of resources which is now delegated to Shift-Refresh and which no 'typical' user will think of.
The FireFox Refresh button's Refresh behavior is pretty lame. Having an easy way to force pages and all related content to reload is key in a browser environment where the underlying resources may frequently change on the server. Between the refresh and last-modified issues described FireFox 3.x is becoming a bit shaky for the stability, especially for applications that are rich in client side styling and script behavior. It's not uncommon for my apps to update CSS or script content several times a day and there's now a good possibility that these changes may not match changes in the underlying application that serves non-static content. This has bit me quite frequently now during development when refreshing pages and expecting to see update content only to find that things like Script files have not refreshed and a few times in production with customers complaining.
One temporary solution might be (thanks to Steve Black for the hint) to force the CSS references in pages to refresh by changing the URL slightly. Like
<link href="wwThreads.css?i=1" rel="stylesheet" type="text/css"/>
The additional querystring will force even FireFox to refresh the data. But that's one heck of a hack. But I may have to resort to this because nothing else works reliably at this point.
So... has anybody else run into this in their applications? In searching around the Web it doesn't appear that there's much talk about this issue - I didn't find anything related to last-modified and a few discussions - which are related - to caching and back button and refresh behavior. It looks like Firefox is trying to be too agressive in caching. Sure, caching is cool for performance, but not if it's at the cost of stale content.
The Voices of Reason
# re: FireFox 3 and Static File Caching Problems
# re: FireFox 3 and Static File Caching Problems
I did change the cache policy in IIS now so that it expires content daily now, but this isn't going to help existing visitors who have the content already cached.
# re: FireFox 3 and Static File Caching Problems
FireFox also has an annoying behavior (I call it a bug)-- if you have a web form with text boxes, select boxes, etc. and hit "refresh", the state of those form elements are left however they were set prior to the refresh. To force them back to true defaults, you have to ctrl+shift click the refresh button. Really stupid, and led to an hour or so of development time lost, thinking my app. was misbehaving.
# re: FireFox 3 and Static File Caching Problems
# re: FireFox 3 and Static File Caching Problems
I get prompted every day or so to update -- but I keep holding off...
# re: FireFox 3 and Static File Caching Problems
I experimented around a little more trying other sites: Google, Microsoft, Yahoo - all of the sites are exhibiting the same behavior with FireFox: no 304's to check modified dates. FF appears to only wait for Expiration before it reloads.
# re: FireFox 3 and Static File Caching Problems
# re: FireFox 3 and Static File Caching Problems
# re: FireFox 3 and Static File Caching Problems
# re: FireFox 3 and Static File Caching Problems
My version of Firefox 2 does not send a request for resources which are still valid in the cache. (But it does send a request when pressing reload; this might have changed in FF 3, I don't know, and I can't check right now.)
Of course, this means you'll have to change the resource's URL if you want to force clients to get the new version. Alternatively, you could modify the caching directives sent by your server so that clients are always required to revalidate (Cache-Control: must-revalidate, see the HTTP spec for details).
# re: FireFox 3 and Static File Caching Problems
It doesn't work properly at least not in the frames page. All other browsers I checked: IE, Opera, Safari, properly check all links on the server including in child frames. Firefox does not.
Firefox also doesn't refresh regular pages on a regular Refresh - it requires Shift-Refresh which is totally bogus. An average user might figure out that his page is not properly loaded and hit refresh to attempt to get it refreshed properly. But hitting Shift-Click is not something that the average user will think of. Heck I still can't keep Shift-Refresh and Ctrl-Refresh and clicks straight.
The Refresh behavior is what's broken IMHO and what is the main cause for the problems I and others describe.
# re: FireFox 3 and Static File Caching Problems
# re: FireFox 3 and Static File Caching Problems
# re: FireFox 3 and Static File Caching Problems
# re: FireFox 3 and Static File Caching Problems
I don't see this behavior (304s being sent on a plain refresh). Basically Refresh appears to be resubmitting the page EXACTLY as it was sent by the last request. So if the last request was a Shift-Refresh to force a full refresh then hitting just the Refresh button does the same again also generating the 304s. But if you just hit the page again from a link or typing in the address bar it will do exactly the same and NOT hit 304s. At least that's what I'm seeing in my setup here.
As I said in the post - I'd expect Refresh to be more agressive in reloading content. That's part of the purpose of Refresh button is to ensure all resources are reloaded.
While I think you can change the behavior via about:config settings, that's not something you'd want to force on your site users.
# re: FireFox 3 and Static File Caching Problems
http://www.scottmccloud.com/googlechrome/
# re: FireFox 3 and Static File Caching Problems
http://clearcachebutton.mozdev.org/
# re: FireFox 3 and Static File Caching Problems
# re: FireFox 3 and Static File Caching Problems
Google Chrome is correctly sending 304 requests, like FF3 should be.
# re: FireFox 3 and Static File Caching Problems
The thing is an average user won't even know that they're seeing old stuff. I've been investigating what I could have done to have prevented this and I can't find a solution. So, not only are they seeing the old site, but I can't even find a way to inform them (the general public user) that they're seeing the old site.
I also have no access to the IIS of the server that the website resides on so if there is a solution by doing someting in IIS it is of no use to me.
I personally don't use Firefox because I can never be certain I'm seeing up-to-date web pages.
# re: FireFox 3 and Static File Caching Problems
I have it pretty automated now where I insert the CSS file's timestamp in the .NET Cache. I add a cache dependency for this item -- where the dependency is the actual CSS file. When I update the file, the cached timestamp is automatically removed from cache and the new timestamp is added into cache on the next request. What's obviously nice about this is that I don't have to manually modify the querystring. An example CSS file name with querystring in the served HTML looks like:
styles.css?v=20080817152536
# re: FireFox 3 and Static File Caching Problems
# re: FireFox 3 and Static File Caching Problems
That's my best guess as to what you're hitting, though I don't think this behavior has changed from Firefox 2 to Firefox 3. But note that if you're not using the former much and it didn't have the files with the ancient Last-Modified date cached... you wouldn't hit the problem.
The issues with reload sound like a bug for sure. Any chance of getting that filed, and ideally a page that reliably shows the problem?
# re: FireFox 3 and Static File Caching Problems
# re: FireFox 3 and Static File Caching Problems
# re: FireFox 3 and Static File Caching Problems
The problem you're seeing is from previous requests of the resource. If there was a Cache-Control header that specified the max age of the file or an Expires header specifically saying when the resource becomes stale, the server told the browsers "Don't worry about requesting this resource before this time." The browsers are doing the correct thing here in not making the request. Essentially there's nothing you can do to force them to reload if they don't want to. Your safest bet is to rename the resource to force the browser to load it and in the future set up your server to only cache files for a shot period of time.
# re: FireFox 3 and Static File Caching Problems
As I mentioned I have a frames based setup that I was unable to get refreshed AT ALL other than forcing a URL change. I've now changed the expiration to a smaller number and that works, but FF doesn't refresh the associated static resources under any manually applied browser action.
# re: FireFox 3 and Static File Caching Problems
# re: FireFox 3 and Static File Caching Problems
# re: FireFox 3 and Static File Caching Problems
Also, if you really want to verify what is being cached have a look at about:cache. You'll get links to both the memory and disk caches. Looking at those you'll see what the browser has cached and when it thinks the content expires.
Obviously this isn't something for your users (your header changes fixed that) but from a development standpoint it's a life saver. If you do it often look for the Clear Cache Button add-on. I have it sitting next to my address bar and can clear my cache with one click.
# re: FireFox 3 and Static File Caching Problems
I have it pretty automated now where I insert the CSS file's timestamp in the .NET Cache. I add a cache dependency for this item -- where the dependency is the actual CSS file. When I update the file, the cached timestamp is automatically removed from cache and the new timestamp is added into cache on the next request. What's obviously nice about this is that I don't have to manually modify the query string. An example CSS file name with query string in the served HTML looks like: styles.css?v=20080817152536
# re: FireFox 3 and Static File Caching Problems
# re: FireFox 3 and Static File Caching Problems
Would be interesting to hear anyone verify this, since it only happens in firefox3. Is this a known problem?
# re: FireFox 3 and Static File Caching Problems
if (forceDontCache)
{
setHeader("Cache-Control", "no-cache no-store must-revalidate");
setHeader("Pragma", "no-cache"); // HTTP/1.0
setDateHeader("Expires", 86400000); // January 2, 1970
}
else if (forceCache)
{
// the w3c spec requires a maximum age of 1 year
// Firefox 3+ needs 'public' to cache this resource when received via SSL
setHeader("Cache-Control", "public max-age=31536000");
// necessary to overwrite "Pragma: no-cache" header
setHeader("Pragma", "");
// this prevents the browser from requesting the resource for 1 year
setDateHeader("Expires", currentTimeInMilliseconds + 31536000000l);
}# re: FireFox 3 and Static File Caching Problems
Has anyone filed a bug for this with Firefox yet? If not, how can we all be so lazy? :)
# re: FireFox 3 and Static File Caching Problems
https://bugzilla.mozilla.org/show_bug.cgi?id=441751
And furthermore, it's just been fixed on trunk! The problem is we still have to support the FF versions that came and will come before this makes it into a release...
# re: FireFox 3 and Static File Caching Problems
I spent a few hours going crazy with the same problem. I found that if I disabled the 'Firebug' extension in FF3, it would request 304's again.
# re: FireFox 3 and Static File Caching Problems
Response.Cache.SetCacheability(HttpCacheability.NoCache)
Response.Cache.SetAllowResponseInBrowserHistory(False)
Response.Cache.SetNoStore()
When I page back now my original page is loaded. It didn't work in FireFox until I added the Response.Cache.SetNoStore()
Hope this may help you.
# re: FireFox 3 and Static File Caching Problems
Anyone know why Firebug is prohibiting the 304's?
# re: FireFox 3 and Static File Caching Problems
I have just found a solution on tech blog: [http://blogs.helion-prime.com/]
have a nice day
# re: FireFox 3 and Static File Caching Problems
It is even worse if your pages are big or when you have extensions like Firebug.
On my webapp I have double request (checked on Apache logs) and even strange renders like the 2 results being merged (I have made a page which doesn't display the same thing every time, and the 2 outputs are melt together O_o, like 2 thread trying to write at same time).
At the moment my only fix is to use Firefox 2, ... or Opera.
# re: FireFox 3 and Static File Caching Problems
# re: FireFox 3 and Static File Caching Problems
However I found that changing the following setting solved the problem (confirming jotabede's idea):
browser.cache.check_doc_frequency = 1
1 = Check for a new version every time a page is loaded
3 (default) = Check for a new version when the page is out of date
See: http://kb.mozillazine.org/Browser.cache.check_doc_frequency
# re: FireFox 3 and Static File Caching Problems
# re: FireFox 3 and Static File Caching Problems
This way although a last-modified is passed to the browser, the expires header forces the ff to create a 304 request each time.
# re: FireFox 3 and Static File Caching Problems
This technique works great in IE 7 and 8, Google Chrome and Opera. In these browsers, when a link is clicked anywhere in the site, I get re-validation, as I should. BTW, for those that say the browser should send a "304" header, the "304" is a *response* header that the server sends to the browser, not a request header.
In FF3, when the links are clicked, I get no re-validation. When a standard refresh is initiated in FF3, *sometimes* FF will re-validate, but most times it won't. When I do a shift-refresh, FF sends the correct headers and performs a complete reload of the page.
This is not per HTTP specs, and should be fixed. I do not like IE, and never have, and would really like to see FF become more prevalent. If they don't fix their validation model, this will not happen.
Here are the headers that I am sending to the browser on most pages:
Cache-Control: public, must-revalidate, max-age=90000, post-check=60, pre-check=60, proxy-revalidate, no-transform
Thes headers should cache the page for 25 hours, but always check to see if the content has changed. As I mentioned, this works in all browsers I've tested except for FF. FF totally ignores these headers. I have also tried many different variations, inccluding changing the values of max-age, post-check, pre-check, etc.
# re: FireFox 3 and Static File Caching Problems
# re: FireFox 3 and Static File Caching Problems
The problem with this is that every person that visits a site more than once must make configuration changes to their browser in order to view the site as it was (mostly) intended. Not a solution.
The only other solution that I can think of is to send no-cahe, no-store and past expires headers to all FF users, requiring browser sniffing, etc. Again, not a solution.
Maybe Mozilla could just fix their browser.
# re: FireFox 3 and Static File Caching Problems
Cache-Control: private, max-age=86400
...and then click refresh, it still goes to the server with if-modified-since. I'm trying to prevent all the if-modified-since checks that tax the server and slow down the page load.
It works if the server is my local machine, but not if it's the ISP server.
Any ideas?
# I dont know if this is relevant
When I went to another laptop and browsed to the original laptop's website, FF3 auto-refreshed the page as expected. Maybe some http headers are ignored when locally browsing?
( still, at least i dont use asp.net webforms anymore ... hit 'BACK' in that environment and its a car-crash eh?)
# re: FireFox 3 and Static File Caching Problems
So i set the following headers in cache as follows and it works for me.
response.setHeader("Cache-Control", "no-cache,no-store");
response.setHeader("Pragma", "no-cache");
response.setDateHeader("Expires", -1);
# re: FireFox 3 and Static File Caching Problems
This probably explains what's going on.
Thanks for exploring this.
Now we have to hope that this make / dumb decision gets fixed soon.