Improve Your YSlow Grade Using .htaccess
This post was authored by Eric Wendelin. To learn more about Eric, click here.
A significant part of your YSlow grade depends on how well your site utilizes optimal caching techniques. By editing your .htaccess file, you can increase your YSlow score by 20 points or so in just 3 minutes!
Quick Intro to Caching
Caching is a browser feature that allows storage of certain types of web files on the client-side. In most cases, we want to have our clients cache our static files like HTML and CSS so that our website is faster after the first request.
Browser caching mainly depends on two things: the headers you send in an HTTP response and the browser your client is using.
There are a couple of things a browser can do when caching depending on the headers used.
- It can check back on every request, and servers will reply with a HTTP status 304 (Not Modified) if the file is indeed the same.
- Only ask the server for the file when the cached one has expired.
The latter case is better for performance because the browser doesn't even ask and therefore saves a lot of HTTP requests.
Setting the Expires Header
One of the best things we can do to ensure good cache-ability is set a far future Expires header:
<FilesMatch "\.(ico|pdf|flv|jpg|jpeg|png|gif|js|css|swf)(\.gz)?$"> Header set Expires "Thu, 15 Apr 2012 20:00:00 GMT" </FilesMatch>
Note here that if your site changes a lot, you'll need to rename/version your files or get clever with your ETags to keep users up-to-date. If you Firebug my site, eriwen.com, you'll see that I do just that. Stay tuned there for a script that can help you automate this.
Controlling Those ETags
ETags are difficult because they take precedence for caching in most browsers. You can change all the headers you want, but if the ETag associated with a file is always the same, caching will never work how you expect. In most situations, you should turn your ETag headers off.
<FilesMatch "\.(ico|pdf|flv|jpg|jpeg|png|gif|js|css|swf)(\.gz)?$"> Header unset ETag FileETag None </FilesMatch>
Yes, you can combine the two snippets:
<FilesMatch "\.(ico|pdf|flv|jpg|jpeg|png|gif|js|css|swf)(\.gz)?$"> Header set Expires "Thu, 15 Apr 2012 20:00:00 GMT" Header unset ETag FileETag None </FilesMatch>
Testing Your New Settings
The best way to see what's going on is to check the "Net" tab in Firebug. You can use a tool like the Live HTTP Headers Firefox extension (there's also one for IE) to verify what headers are being sent. NOTE: If you refresh the page instead of clicking a link, Firefox will recheck all files it has cached. This is not the test you're looking for.
You want to make sure everything is occurring exactly as you intended. Now is the time to bring out your inner control-freak.
These are just 2 simple ways to maximize caching (and therefore speed) of your site. There are lots of other headers to play with, but I find that these two give the biggest bang for your buck. Share your caching tricks in the comments!
About Eric Wendelin
Thank you for hosting such a good article, Dave, another thing difficult to find a tutorial around is about gzipping resources (js, css) …any hint about this topic?
I have googled around but nothing good came out: did you successfully try to gzip the site resources or do you know a good article about this?
Thanks for your interesting work though!
@Stefano: Yes, GZipping is the last step here.
Here are a few lines from my .htaccess that WOULD do this if my hosting provider let me :(