Improve your web site performance - tips & tricks to get a good YSlow rating

Published on Friday, May 9th, 2008

When YSlow was released to indicate how well a web site performed, there were a lot of people disappointed, and perplexed, by their own score. Overall, I think performance is underrated, so I thought I’d give you some short guidelines how to improve the performance of your web site.

YSlow, for those not familiar with it, is a tool based on the research done by Steve Souders (ex-Yahoo!, now Google) and the Yahoo! performance team, to help people improve web site performance and find common bottle-necks.

The rules and their values

In YSlow, there are 13 rules, which have different values in the overall score, that goes from 0 to 100 (the one rule that has fallen out from the original 14 rules in the High Performance Web Sites book is about AJAX and caching). These are, with respective point values (taken from Dissecting YSlow):

Value 11

Value 10

Value 5

Value 4

Value 3

Rule 1 - Make fewer HTTP requests (CSS Background images)

Value 2

Rule 7 - Avoid CSS expressions

What rules to care about

This is where it becomes a little bit more interesting. Most rules everyone agrees about, but there are some that has caused a little bit of a controversy in there. While YSlow: Yahoo’s Problems Are Not Your Problems goes into detail a little bit more, I would argue that the only rule I would definitely want to be optional, and turned off by default, is the Use a Content Delivery Network (CDN) one.

Basically, using a CDN is about having your static content spread out through servers across the world, to offer something as geographically close to your end user as possible, and to meet traffic spikes in the most prepared manner. The fine print here is that CDNs are extremely costly, and the need for one really only applies to enormously high-traffic web sites such as Google, Yahoo! etc.

To force this rule upon us mere mortals with less than one million visitors per day or so is pretty much a waste. CDNs are a good thing, no doubt, but since it only applies to a minority, it should be left out. This means that the best score you can get for a web site is 90/100, so start considering 90 to be top notch/high score.

Some other rules can discussed, but generally, all the rest of them are good ones.

Making improvements

The ones such as where to put your CSS and JavaScript files, minifying them and packing them together, avoiding redundant code and making files external are quite self-explanatory; so I’ll leave them out of the discussion here. Instead, I’d like to show you how to improve the other ones on an Apache server, version 2 (which is the most popular web server on the web); other alternatives are mentioned at the end of the post.

The bases for the following advice is that you have access to two files: httpd.conf, which is located in your Apache installation folder, and .htaccess, which is the root of your web site (if it’s not there, just create it).

How to Gzip compontents

Gzipping is the most effective way to compress files, and the way it works is that a web browser states to server that it accepts gzip when it makes a request, and the server then returns the content in a gzipped format. This means that what’s sent over the wire is much, much smaller, thus decreasing bandwidth usage and request time. After the web browser has received the file, it unpacks it and the file works in its original format.

Open httpd.conf and uncomment this line (for those new to this file, a hash mark (#) is used to comment out a line; just remove it to activate that line):

LoadModule deflate_module libexec/apache2/mod_deflate.so

Then you have two alternatives to choose what file types you want to compress. Typically, you’ll want to compress the HTML output, CSS, JavaScript, and any other text-based format. Add any of the alternatives below to the httpd.conf file.

Alternative 1

AddOutputFilterByType DEFLATE text/html text/plain text/css text/javascript
application/x-javascript

Overall, this approach works great, but I’ve had problems where specifically JavaScript files weren’t compressed.

Alternative 2

This approach is rather based on compressing everything, and then specify which file types to exclude from that. Typically, you don’t want to compress images and some other formats, since they are already so compressed to begin with.

SetOutputFilter DEFLATE
DeflateFilterNote ratio
SetEnvIfNoCase Request_URI \.(?:gif|jpe?g|PNG)$ \
    no-gzip dont-vary
SetEnvIfNoCase Request_URI \
    \.(?:exe|t?gz|zip|bz2|sit|rar)$ \
    no-gzip dont-vary
SetEnvIfNoCase Request_URI \.pdf$ no-gzip dont-vary

Covering up for web browsers which might fail

Naturally, there are web browser out there claiming to support gzip when talking to the server, but not living up to it in practice. Amongst these are Internet Explorer (shocker), at least up till version 6, so you can also add this to the file:

BrowserMatch ^Mozilla/4 gzip-only-text/html
BrowserMatch ^Mozilla/4\.0[678] no-gzip
BrowserMatch \bMSIE !no-gzip !gzip-only-text/html

An alternative way to Gzip

Chances are, your host maybe doesn’t allow you to edit the httpd.conf file, meaning you can’t rely on Apache to do this for you. However, I found another way to do it through Reducing Bandwidth Usage when Deploying Web Applications. The idea is to locally gzip your files(s), and then name them with a .gz.js or .gz.css extension, to get the web server and requesting web browsers to treat them as pre-gzipped files.

Open up the Terminal where your files are, and gzip them like this:

gzip -c originalFile > myDeployFile.gz.js

When it comes to the HTML content itself, many tools out there supports compressing it on its own (for you bloggers, WordPress has this under Options > Reading: “WordPress should compress articles (gzip) if browsers ask for them”).

How to configure ETags

ETags are HTTP headers, which identify when a file was changed. The basis is that a web browser will only get that file if the ETag has changed since the last request. There is a very simple way to tell Apache to add an ETag consisting of the file’s modified time and its file size.

Open up the .htaccess file, add this line, and you’re good to go:

FileETag MTime Size

How to add Expires headers

First, let me explain how requests for a file works:

  1. If the visitor has an empty cache (in regards to your content), it will fetch all necessary files from the server.
  2. If the visitor has your files in the web browser cache, it still has to send a conditional GET request to your server, to compare if the last modified time of the file in the web browser cache is the same as the file on the server. If not, it fetches a new version of the file in question.
  3. If a file has a future expires value set, it won’t even go to the server at all until that time has occurred, thus leading to completely eliminating that request.

Therefore, using expires headers are extremely efficient for static files in your web site. To do it, begin with opening up the httpd.conf file and enable the expires module:

LoadModule expires_module libexec/apache2/mod_expires.so

Then, open up the .htaccess file and add what file types you want to set expires header for, and how long that time should be:

Alternative 1

ExpiresActive On
ExpiresByType text/css "access plus 3 days"
ExpiresByType application/x-javascript "access plus 3 days"
ExpiresByType image/gif "access plus 3 days"
ExpiresByType image/png "access plus 3 days"
ExpiresByType image/jpeg "access plus 3 days"

Alternative 2

Another option can be to turn on expires header for everything:

ExpiresActive On
ExpiresDefault "access plus 3 days"

The value needed to get a good YSLow grade is to have expires headers set at least 48 hours into the future, but in practice, you need configure the values that suits your needs the best. Note: If you need to push out new files to the end user and overriding the existing web browser cache, you either have to change the actual file names, or adding a query string to the requests with a new value. For example, changing 19 in the query string below to, e.g. 20, would force the web browser to get a new version from the server.

<link rel=”stylesheet” href=”/css/base.css?19″ type=”text/css”>

We want proof that this works!

Curious and hungry for knowledge, I naturally had to try all this out to improve the end user experience for you, my dear readers. The result of implementing the above solutions are a YSlow ranking for Robert’s talk of (mostly) 80, and for the DOMAssistant web site, a value of 88.

Someone visiting Robert’s talk for the first time will get 30 HTTP requests, while a returning visitor will only have 6 HTTP requests. Quite an improvement, right? :-)

The reasons for not getting 90 (top score unless you’re Donald Trump, remember?) is, for Robert’s talk, my Flickr images and a couple of statistics scripts. With the DOMAssistant web site, it’s only statistics script holding it back from being top notch.

Other environments

Internet Information Server (IIS)

Django, Apache, and Lighttpd

Also, if you want to read more about what I touched on above, I definitely recommend reading Tools for optimizing your website: Etag and Expire headers in Django, Apache, and Lighttpd.

Performance does matter

At the end of the day, I want you to get good web sites that are incredibly fast to load. Therefore, I sincerely hope you’ve learned something from this that will improve the future performance of the web sites you’ll be working on.

Good luck performing! :-)

20 comments

  • Neovov
    May 9th, 2008 at 1:17

    A big thanks, your post is excelent and came precisely when I need some informations about that.

    But, I have just one note : Most of the time, visitors have a browser’s cache full.. So, in that case configuring, ETags, Expire and GZip isn’t a big improvement…

  • Georges Jentgen
    May 9th, 2008 at 7:04

    Nice post Robert! Really enoyed reading it. GZipping content on the serverside is always the best way to start, as the gziping does a very good job. In my last project I have had a compression rate of almost 70%! This was especially good as it was a webapp with a quite complex ui written in js and a lot of AJAX going on…

    You couldn’t notice the AJAX request going on in the background after I turned on gzip compression.

    But I would suggest to always develop without those things turned on at first, as it leads you to blow up your code because you think that it is compressed anyway… you should NOT! :)

  • links for 2008-05-09 | Libin Pan
    May 9th, 2008 at 7:43

    [...] Improve your web site performance - tips & tricks to get a good YSlow rating - Robert’s talk … Improve your web site performance - tips & tricks to get a good YSlow rating (tags: web performance yahoo yslow) [...]

  • Morgan Roderick
    May 9th, 2008 at 14:42

    This is from memory, so might be inaccurate, BUT!

    One thing to note, is that it’s usually better to use httpd.conf, or another .conf file on your apache server to set directives.

    .htaccess files should be a last resort if you cannot modify your .conf files, as the server will evaluate it for each request instead of once, when the server starts.

  • Robert Nyman - author
    May 9th, 2008 at 15:22

    Neovov,

    Glad to hear that my timing was right. :-)
    With a full cache, ETags and Gzip won’t matter that much, but Expires is still great, since it completely removes conditional GET requests for each file, to compare if the the web browser have the latest version in the cache.

    Georges,

    Yes, the result is fantastically good! :-)

    Morgan,

    Interesting to hear. If that’s true, and one have access to the httpd.conf file, by all means, use that. If you find anything about this please let me/us know!

  • NICCAI
    May 9th, 2008 at 19:45

    Robert, will you share your YSlow scores for these sites before making the above tweaks? - just curious. Thanks and really handy article. The YSlow team should link to this.

  • Robert Nyman - author
    May 9th, 2008 at 20:46

    NICCAI,

    Thanks! I’d be very happy if they were to link to this article. :-)
    Improving the performance for Robert’s talk has been a gradual process, where I started by moving the JavaScript files down, compressing them etc so unfortunately I can’t just roll back to see the previous score.

    But if I remember correctly, it was somewhere between 50-60, so the improvement was substantial!

    With the DOMAssistant web site, the irony is that I don’t use any scripts on it (except for stats purposes), so the grade was already close to 70 when I started. Still, getting 88 is something I’m quite pleased with as well. :-)

  • Mike
    May 10th, 2008 at 19:47

    Do you recommend using gzip for CSS and js files if they are 20 to 30k or under?

    I am having my host configure apache to add expires headers, and enable gzip, but they said that my stylesheets are too small to be worth it. Curious to know what you guys think, if there is a minimum size where gzip would not do you any good.

  • Jennifer Edmondson
    May 11th, 2008 at 2:06

    au.yahoo.com scores 75 ^_^

  • Andreas
    May 11th, 2008 at 20:01

    Nice! I’ve added most of them to my framework but wasn’t sure about the ETags-one. Cheers for clearing that up.

  • Robert Nyman - author
    May 12th, 2008 at 10:07

    Mike,

    From what I’ve read, at least, gzip is supposedly always a good idea as long as the files are over 1-2 KB.

    Jennifer,

    Oh, wow. Maybe time for some internal spanking? :-)

    Andreas,

    Regarding ETags, what might be interesting to know, with multiple servers and load-balancing, ETags might also be a less good thing. Then you can remove ETags completely from your files instead, in the .htaccess file:

    FileETag None

  • Chasing requests | icaaq
    May 19th, 2008 at 22:30

    [...] been allot of optimizing for me the last couple of weeks. I’ve been reading up on yslow issues, paths to a faster loading sequence, high performance websites and much much [...]

  • Chinese SEO Expert
    May 21st, 2008 at 1:37

    Great article, thank you very much Robert! I am thinking to improve my web site performance. This articles will help me a lot!

  • Optimizing web site performance - Waldek Mastykarz
    May 26th, 2008 at 21:49

    [...] Robert Nyman, has written a great article about optimizing web site performance using YSlow: an add-on for Firebug for Firefox. In his article Robert presents not only the add-on [...]

  • lillbra » Blog Archive » Tänkvärda tips om prestanda
    May 27th, 2008 at 6:25

    [...] du förbättra din sajts prestanda. Robert Nyman berättar mer exakt hur du gör detta i artikeln Improve your web site performance - tips & tricks to get a good YSlow rating. Det handlar till exempel om [...]

  • Minify your JavaScript - and save the KB’s for later (Imtech JavaScript Minificator - Free Tool) - Waldek Mastykarz
    June 5th, 2008 at 6:54

    [...] stumbled upon an article of Robert Nyman about YSlow - a performance measurement Firefox add-in: Improve Your Web Site Performance - Tips & Tricks To Get A Good YSlow Rating. Because the tool presents not only the test results, but also helps you fixing the discovered [...]

  • Summer break - Robert’s talk - Web development and Internet trends
    June 13th, 2008 at 0:12

    [...] Improve your web site performance - tips & tricks to get a good YSlow rating [...]

  • zuborg
    October 27th, 2008 at 20:57

    I would also recommend to use this online free performance testing tool - http://Site-Perf.com/

    It measure loading speed of page and it’s requisites (images/js/css) like browsers do and shows nice detailed chart - so you can easily spot bottlenecks. It’s very detailed and accurate, supports a lot of features like Keep-Alive and HTTP-compression.

    Also useful feature is that this tool can measure quality of internet link of your server.

  • Robert Nyman - author
    October 28th, 2008 at 10:49

    zuborg,

    Thanks for the tip, seems to be a addition! Developed by you?

  • zuborg
    November 9th, 2008 at 22:45

    Robert, you are welcome )

    Yes, I’m author.
    Hope you find it helpful.

Share your thoughts:

HTML: You can use these tags: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong> . If you want to display code examples, please remember to write &lt; for < and &gt; for >.

Comment preview

Top results