IIS, Optimising Performance, 304 status codes, and one stupid browser…

Well, I thought I’d start my play in earnest after last weeks DevWeek, I thought I’d experiment with various performance improvements that came out of Robert Boedigheimer’s (@boedie) talk.

First up, a play with expiry of content.  We host all of our ‘assets’ (images, css, javascript, and flash) from a content delivery network style setup.  We don’t currently use a CDN for anything other than our games, but the concept is the same – so long as the assets are hosted on a separate URL to the content, then the location of those assets isn’t an issue.

Setting Up Expiry for Assets in IIS 7

In IIS manager left click on the website, folder or indeed file that you wish to set expiry on.

image

From the ‘IIS’ section in the main pane (make sure you’re on features view for this) double click on ‘Http Response Headers’.

image

You will see in the right hand pane the option to ‘Set Common Headers…’

image

This gives you the following dialog:

image

 

You can see here, I’ve enabled ‘Expire Web content’ and am expiring it after 20 days.  You can set a fixed expiry time too, though I’ve never done this – I can imaging it’s more maintenance overhead to ensure you always keep content ‘cached’ at various points in time, though it’s there if your use case demands it.

 

Fiddlers 3(04)

Ok, so that’s all yes? Well, yup, that’s it.  Fire up fiddler and load up one of your assets – you should see something like the following:

image

So, all is well on first load – we get a status code 200 and we can see that caching is enabled and has a max-age of 1728000 (20d * 24h * 60m * 60s), so we know that our next request should be cached and shouldn’t hit the server.

Hit Refresh…

image

Erm… why are you still hitting my server even if only to be told 304 (not modified), resource hasn’t changed…  So why the round trip?

Turns out hitting refresh on any browser will indeed make that round trip – the refresh button is almost an override for the local browser cache and says ‘go and double check for me’ – I’ve tested in IE8/9, Firefox and Chrome and they all do this.

So how do I avoid the round trip for non modified resources?

Turns out you’re already doing it.  Instead of clicking refresh, click into the address bar and press return.  You will find the resource loads up again no problem, but there is now no round trip to the server and no 304 response.  Well, it loads up no problem in IE or Firefox, but there’s another pesky browser on the block…

Hmmm, Google Chrome? Why won’t you play ball?

Seems that pressing return in Chrome behaves in the same way as if you’d hit the ‘refresh’ button and still issues the request (and naturally gets the 304).

Should I worry?

Well, no – we have only been testing single resources here.  If I navigate to a page by typing in the URL and pressing return (first run) you’ll get the usual 200 status codes, and you’ll get the usual assets caching.  If you press return to ‘reload’ that page in chrome, then you will get all of the round trips back and forth with the corresponding 304s.

But, if you navigate to that page (after you’ve had your code 200’s) via either a bookmark or a google search (essentially, via a hyperlink) then jobs a good un and it doesn’t issue the requests.

I’m not sure why Chrome behaves differently to the other browsers in this regard – I could understand if it didn’t have a ‘refresh’ button, but it has.

 

I write this up as it caused an hour or so’s pain as I played around with IIS caching, as I’ve recently switched to Chrome as my default browser.  It was only chance that I tried the assets in the other browsers when Chrome wasn’t doing as it claimed it should be that I realised it was just a chrome side effect and really only came into play when I was ‘debugging’.

Hope it’s useful to others.

  • There’s a good SO thread on what the various browsers do with regard to cache headers when the user presses F5, CTRL+F5 etc:

    http://stackoverflow.com/questions/385367/what-requests-do-browsers-f5-and-ctrl-f5-refreshes-generate

  • Terry Brown

    superb – although it doesn’t cover the case of ‘return’ pressed, but the rest of it is v. good – useful table for sure.

  • Thanks so much for this, great write up.

  • Terry, awesome article. I am putting a link to this on my blog, is that OK?

  • So does CHROME actually make the 304 round trips? Because the majority of our visitors use the Chrome browser?

  • terry_brown_uk

    sure thing 🙂 Just make sure attribution links it back here please 🙂

  • I had to remove all the CacheUntilChange settings as well. That was messing me up and also causing 304 responses. I got my request/response first hit from 69 to 10. Awesome. This will greatly reduce resources on the server. Can wait to see the results over the next week or two.