views:

82

answers:

4

I have a page with lots of small images (icons). When used with chrome, each time the page is reloaded, chrome requests each icon from the server with if-modified-since header.

All icons are served with expires and max-age headers. Firefox loads images from its cache.

Why is chrome doing that and how can I prevent it?

Thanks

A: 

That sounds like it's trying to avoid an outdated cache by asking the server whether the images have changed since it last requested them. Sounds like a good thing, not something you would like to prevent.

Florian Mayer
+2  A: 

Modern browsers are getting more complex and intelligent with their caching behaviour. Have a read through http://blogs.msdn.com/b/ie/archive/2010/07/14/caching-improvements-in-internet-explorer-9.aspx for some examples and more detail.

As Florian says, don't fight it :-)

Andy
Well... I'm not excited about getting many unneeded requests to my server and ruining user experience at the same time.Thanks for the interesting read anyway.
A: 

A quick experiment with Chrome’s inspector shows that this only happens when the page is reloaded, not when it is loaded normally. Chrome is just trying to refresh its cache. Think about it — if you set Expires and Max-Age to several decades, are you asking the browser to cache that resource and never check to see if it gets updated? It’s caching the resource when it can, but when the page needs to be refreshed it wants to make sure that the entire page is refreshed. Other browsers surely do it too (although some have an option for the number of hours to wait before refreshing).

Thanks to modern browsers and servers, refreshing a large number of icons won’t be as slow as you think — requests are pipelined to eliminate multiple round-trip delays, and the entire purpose of the If-Modified-Since header is to allow the server to compare timestamps and return a "Not Modified" status code. This will happen for every resource the page needs, but the browser will be able to make all the requests at once and verify that none of them have changed.

That said, there are a few things you can do to make this easier:

  1. In Chrome’s inspector, use the resources tab to see how they are being loaded. If there are no request headers, the resource was loaded directly from the cache. If you see 304 Not Modified, the resource was refreshed but did not need to be downloaded again. If you see 200 OK, it was downloaded again.

  2. In Chrome’s inspector, use the audits tab to see what it thinks about the cacheability of your resources, just in case some of the cache headers aren’t optimal.

  3. All of those If-Modified-Since requests and 304 responses can add up, even though they only consist of headers. Combine your images into sprites to reduce the number of requests.

jleedev
I'm really confused about all this. Sure, refresh should check for new content, sounds right. But chrome sends those requests for normal page loads as well.To make things even more confusing, it seems the behavior has now suddenly changed and images are fetched from cache without any if-modified requests. I haven't changed anything o_OI hate it when systems are indeterministic like this.
@user As far as I can tell, that’s the correct behavior. Andy’s link about IE paints a similar picture — assuming proper cache headers, the first time in a session, the resource is always checked for updates, and after that is always cached until a reload is requested. It’s not very straightforward, I know, and maybe the best I can say is that the people who write browsers, proxies, and servers have invested more hours into this than you or I. I’d trust their judgment.
jleedev
A: 

Assuming you are running Apache, you can try explicitly setting up cache lifetimes for certain files types and/or locations in the filesystem.

<FilesMatch ".(jpg|jpeg|png|gif)$">
Header set Cache-Control "max-age=604800, public" # 7 days
</FilesMatch>

or something like

ExpiresByType image/jpeg "access plus 7 days"
ExpiresByType image/gif "access plus 7 days"
ExpiresByType image/png "access plus 7 days"

Typically, I will group types of files by use in a single directory and set lifetimes accordingly.

Browsers should not request files at all until this ages have expired, but may not always honor it. You may want/need to futz with Last-Modified and ETag headers. There is lots of good info on the web about this.

MPD