Caching

Hi. Ive just run PageSpeed (part of FireBug) on my webpage and its highlighting caching issues (the lack of). Ive been reading this page: Optimizing cache

I cant find a decent tutorial on the net that clearly shows how to use Expires/Cache-Control max-age/Last-Modified/ETag. Does anyone know of any good resources that show how to do this? I guess this code needs to go in the htaccess file?

It’s complex, probably more than it needs to be. In my case centrally define the path to most css/js and images, so I can change the file name and URL when I need to ensure fresh requests.

I use <FilesMatch> in a .htaccess file to set max-age headers.

Looks a bit like this:


#30 days for CSS, JS files
<FilesMatch "\\.(css|js)$">
   Header set Cache-Control "max-age=2592000, public"
</FilesMatch>

# 14 days images
<FilesMatch "\\.(png|jpe?g|gif)$">
   Header set Cache-Control "max-age=1209600, public"
</FilesMatch>

max-age should avoid even conditional header requests and serve the files directly from the cache.

Thanks Cranial. I invetiably have a few questions!:

  • Why have you only set css/js to expire after 30 days and images to expire after 14 days? Ive read that you can set this up to a year in the future which means the user’s browser wont bother trying to get a copy from the server until a year later.

  • Can you expand on “… centrally define the path”? If I had my css files in a folder called ‘css’ and my js files in a folder called ‘js’, would the line of code be:
    <FilesMatch “\css.(css)$”> and <FilesMatch “\js.(js)$”> respectively?

  • When you do change the css file, do you have to rename that file (and update the paths to it in the html page) so that the browser is forced to get the new copy? (I believe this is called ‘fingerprinting’)

Many thanks.

I can’t explain the 30/14 days, it’s just a whim. You could go for a year if you’re confident you can update the URLs. I suspect most browsers would purge from the cache before that time anyway, depending on how often the visitor visits your site.

By centrally define the path, I just mean that my PHP page template defines the path to the file, and every page on the site references the file from that template. So if I change the file from style_1.0.css to style_2.0.css I only have to change one template file, and not sixty thousand pages that all call style_1.0.css

AFAIK <FilesMatch> only works on the file name component of the URL, not the directory. So you can’t use directory paths as part of the match pattern.

<FilesMatch “\css.(css)$”> is incorrect syntax. The \ is an escape character so that the . is treated as a literal period, and not “any character” wildcard (this is a regular expression). The $ marks the end of the file name

So <FilesMatch “\.(css|js)$”> matches all files that end with either .css or .js

<FilesMatch “^header\-”> would match all files that begin with header- (header-bg.png, header-logo.jpg etc.)

Thanks Cranial.
I think youre right about the 30/14 days point. I may play about with these durations to see if it makes any difference. At the moment Im using PageSpeed wich is Google’s web performance addon for FireBug. Im trying to get my score as high as possible (at the moment Im getting 88 out of 100 on most pages). Google is making a big deal on the speed of web sites and caching, but theres seems to be a lack of information on the subject. Thanks for your help.

Ive just added your code to my htaccess file, but when I make a change in the CSS file, I can refresh my browser and see the change. If this code was working then that shouldnt happen should it? (Until I empty my cache).
Thanks

Are you using the refresh button, or just highlight the address and pressing enter? It could be that refreshing causes the browser to ingore cached files. I also noticed recently that Firefox seemed less inclined to cache than Chrome.

Are there other cache headers being sent (like ETag or Expires?) I don’t know if they might cause a conflict.

If you want to know exactly what headers are being sent, you could try either the Firebug or Live HTTP Headers add-on on Firefox. Both will show you exactly what headers were sent to and from the server.

Hi,
I was hitting ‘refresh’ in FireFox.

Ive just used FireBug to get the headers for the CSS file.
The relevant headers under the Headers tab are:
Vary Accept-Encoding,User-Agent
If-Modified-Since Sun, 10 Apr 2011 17:25:23 GMT
Cache-Control max-age=0

And under the Cache tab it says:
Last Modified Mon Apr 11 2011 08:52:29 GMT+0100 (GMT Daylight Time)
Last Fetched Mon Apr 11 2011 08:52:29 GMT+0100 (GMT Daylight Time)
Expires Mon Apr 11 2011 10:18:15 GMT+0100 (GMT Daylight Time)

Do you think any of that will conflict?
Thanks

max-age 0 might be your problem. What happened to 30 days or a year?

Apologies, I removed the code from the htaccess file! Ive now reinstated it and can confirm its now:
Cache-Control max-age=2592000, public
It still doesnt seem to affect anything.
Ill continue to have a play with it, but any ideas or sample scripts would be much appreciated!
Thankyou.