Take the 2-minute tour ×
Webmasters Stack Exchange is a question and answer site for pro webmasters. It's 100% free, no registration required.

I had an epiphany earlier when reading codinghorror. On a content website (blog/forum/website) the basic things rarely change if at all. So I was wondering if there was a way to cache them and only re-download if something changes?

I guess there's two questions here:

  1. Do browsers cache CSS/Javascript, if so how long, can I change how long?
  2. Do I have to write a simple Javascript program that checks if the CSS/JS changed and download if necessary or is there a framework that handles it?
share|improve this question
add comment

2 Answers 2

up vote 2 down vote accepted

You can use your .htaccess file achieve this. FYI This is exactly what programs like YSlow! and Google page speed tell you to do when they talk about setting far future expiration dates for static media.

I use the following code, which sets the cache expiration date to 2099, removes entity tags and enables gzip. Googling for this kind of thing will throw up all sorts of other ways to achieve the same result and I'm certain most webmasters have their own favorite way of doing this.

Copy/paste the code into your .htaccess file and upload.

#####################################################
# CONFIGURE media caching
#
<FilesMatch "\.(ico|pdf|flv|jpg|jpeg|png|gif|ico|js|css|swf)(\.gz)?$">
Header set Expires "Thu, 15 Apr 2099 20:00:00 GMT"
Header unset ETag
FileETag None
</FilesMatch>

<IfModule mod_deflate.c>
<FilesMatch "\.(js|css|php|html)$">
SetOutputFilter DEFLATE
</FilesMatch>
</IfModule>
#
#####################################################
share|improve this answer
    
Note that this tells clients to cache any matching files essentially forever. Given than even your static files probably will change sometime before year 2099, you should only use this method if you're prepared to deal with this issue somehow, e.g. by including a version identifier in all static resource URLs. –  Ilmari Karonen Apr 28 '12 at 22:08
    
Also, just out of curiosity, why are you unsetting ETags? Granted, they won't be of much use with such a distant expiration date, but I don't see what harm there would be in leaving them in. –  Ilmari Karonen Apr 28 '12 at 22:40
1  
@IlmariKaronen have a look at the section on ETags here, basically if you're not validating them they have no use and without that validation they get a 200 rather than 304 response. The 200 is comparatively slow, it's a minor speed point but worth the go. –  toomanyairmiles Apr 28 '12 at 22:50
    
@toomany that Etag thing is only relevant if you are serving content from multiple servers, most people don't even have a full server to themselves. Also I believe Expires can only be set up to one year in the future. –  DisgruntledGoat Apr 29 '12 at 17:31
    
@DisgruntledGoat I'm choosing to trust Yahoo's guidance on this, they recommend it as a practice and it does make sense. The expires headers work in practice, but I will be looking at mod_expires for the future as it seems like a better route. –  toomanyairmiles Apr 29 '12 at 17:39
show 2 more comments

Yes, browsers do cache CSS and JavaScript. Toomanyairmiles has already shown you one way to set the cache lifetime of CSS / JS files in an Apache .htaccess file; another way to do it is to use mod_expires:

ExpiresActive On
ExpiresByType text/javascript "access plus 1 week"
ExpiresByType text/css "access plus 1 week"

This tells browsers to cache any CSS / JS files for up to one week — that's long enough to keep requests for such files to a minimum, but still short enough that you won't have to worry about someone's browser retaining an old style sheet from last year in its cache.

(Of course, this only works if your server is using the correct MIME types for these files, but if not, that's a problem which you should fix anyway.)


Now that you've set a long cache lifetime for your static files, the next problem you'll face is getting them refreshed quickly when you do change them (as you almost surely eventually will). A common solution is to append a dummy query string containing a revision number to the URLs, like this:

<link rel="stylesheet" type="text/css" href="/static/style.css?v001" />

The server will ignore the query string (since the URL points to a static file), but the browser will treat it as part of the URL. That way, after you've updated the style sheet, you just need to remember to change the version number to get browsers to load the new style sheet instead of the old. (If you want to get really fancy, you can use a script to generate the version number automatically based on the last modification timestamp of the file.)

In fact, the StackExchange software on this site uses something very much like this trick. If you look at the source of this page, you'll see that the main stylesheet URL looks like this:

http://cdn.sstatic.net/webmasters/all.css?v=e42c8b75839a

Here, the ?v=e42c8b75839a is presumably a version identifier which changes whenever the style sheet is updated. Looking at the HTTP headers e.g. in Firebug, you can also see that the style sheet has a one week cache lifetime (max-age=604800) like I suggested above.

share|improve this answer
    
I recently read about doing this with mod_expires and had been meaning to research it, thanks for the run down. –  toomanyairmiles Apr 28 '12 at 22:53
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.