Yslow: going from F to A

An introduction to Yslow

Yslow is a tool to help you speed up your website. It’s an add-on for Firefox—or rather, an add-on to an add-on: Yslow installs on top of the popular Firebug add-on. So first you install Firebug, then you install Yslow.

When you run Yslow, it will analyse your web page according to 13 performance rules; for each rule, you receive a grade from A (best) to F (fail). You also receive an overall grade and a score (out of 100). At the time of writing, both Google.com and Yahoo.com score 96 (a high A); most websites get an F grade.

The scoring might seem harsh, and you might be tempted to dismiss these performance rules; but Yslow has been created by Yahoo’s Exceptional Performance team, and their rules deserve your respect. If you follow the rules to the best of your ability, improving your Yslow score, then you will see a significant performance improvement for your website.

If you look at the rules, you may notice a common theme: they are all concerned with components of your web page, such as javascript files, stylesheets, and images. The rules ignore the speed of your server, your databases, and other back-end issues—these only account for about 10–20% of the response time. The other 80–90% of response time is spent on the front-end; this is Yahoo’s golden rule of performance. You may also notice that the rules say nothing about your actual HTML coding practices; again, that’s because the efficiency of your markup has little effect on the performance of your pages: (X)HTML accounts for only about 5% of front-end response time, with the other 95% chewed up by components (JS, CSS, images, Flash, and so on). Next time a markup purist declares that you should use the minimum possible HTML, because it makes your site much faster, please point him in the direction of Yahoo’s Exceptional Performance team, who know better.

Using Yslow: from F to A

Before you start using Yslow, bear in mind that it’s a serious optimisation tool for webmasters who have already covered the basics. For example, Yslow won’t warn you when you have large images that could be compressed. If your files are just too damn large, then you should worry about that first.

When I first ran Yslow, I was surprised by my grade: an F (55). I was expecting to score well; I was expecting Yslow to pat me on the back for my good code. Not so! It turned out I had plenty of room for improvement.

Probably no-one here can afford a decent CDN (I know I can’t). In practice, this means that your maximum score is limited to 90; so in order to get an A grade, everything else must be perfect. You may also be further limited by other practical constraints—in particular, your score can be crippled by ads. With this in mind, just try to get your score as high as you reasonably can. Remember that most websites, even large corporate ones, score an F (here’s a few: ibm.com, unilever.com, goldmansachs.com, bp.com). Even a C grade is an achievement to be proud of.

Let’s go through each performance rule. Here’s the website I was working on: The Badminton Bible

1. Make fewer HTTP requests

For this rule, Yslow separately counts your javascript files, CSS files, and CSS images; it deducts points when you have too many. The following are the maximum numbers you can have without losing any points:

  • 2 stylesheets
  • 3 javascript files
  • 6 CSS background images

It’s important to note that Yslow does not deduct points for content images (). This means that you could inflate your Yslow score by using for decorative images! This would be a silly thing to do: the HTTP request is still there, even though Yslow doesn’t penalise you for it. However, this helps explain why some badly-coded sites get quite good Yslow scores.

The first two items were not a problem. I have one screen stylesheet and one print stylesheet; and I had three javascript files. I had around 30 CSS images, however.

I used Smartsprites to help make CSS sprites. This utility takes most of the work out of creating and positioning your CSS sprites. Unfortunately it’s a pain to install: you need to install and configure Apache Ant first.

Creating the CSS sprites was the single most time-consuming item on my Yslow shopping list—by far. It takes a fair amount of patience. I added them only a few images at a time, and checked the results. I found that, although Smartsprites did most of the work, I still needed to edit the new CSS occasionally: Smartsprites is not clever enough to do everything automatically. I also had to edit one of the sprites, just slightly, to remove a small blemish.

I divided my images into four sprites: two non-repeating, one vertically repeating, and one horizontally repeating. For instance, here’s one of my sprites (this link is guaranteed to go stale; note the version suffix, and see rule 3!).

Overall, this rule is quite important; but the CSS images part is definitely the hardest thing to implement. If you’re in a hurry or impatient, this is not the place to start!

2. Use a CDN

You’re having a laugh.

Good for Yahoo; absurdly expensive for me. I’ll pass, thanks, and dream of the day when I have enough money to throw some at Akamai.

For the uninitiated: CDN stands for “Content Delivery Network” (the D can also stand for “Distribution”). Instead of using only one server, your website resources are served from a whole network of servers spread across the globe. As well as reducing the distance between server and client, this helps you to spread resources across multiple hostnames and thereby increase parallel downloads. Yahoo recommends a minimum of 2 and a maximum of 4 hostnames (see rule 9). Needless to say, commercial CDNs cost more money than most website owners can afford. There are some free alternatives such as CoralCDN, but these don’t seem to provide the same service (they are intended more to guard you from bandwidth spikes than to speed up your pages).

If you can’t afford a proper CDN, then tinkering with a free one is probably a waste of time; you might even slow your website down. When Yahoo say, “Use a CDN”, they are not thinking of Coral. You can’t get everything for free.

3. Add an expires header

This is the single biggest component of your Yslow score: it accounts for 15–16%, so addressing this can make your score increase by one or even two grades. I added this to my .htaccess file:

# Set far-future expiry for images, css, and js
# Remember that you MUST change the filename whenever you update these items!

ExpiresActive on
ExpiresDefault "access plus 10 years"

ExpiresActive on
ExpiresDefault "access plus 2 months"

This was easy to implement, but you have to be careful. I now add version numbers to my stylesheets, javascript files, and images. That way, whenever I want to update them, I ensure that the browser fetches a new copy. If you don’t change the filename, the browser will never fetch a new copy (unless the user hits f5 or clears his cache).

As with CSS sprites, this rule imposes a maintenance burden. But in my opinion, it’s worth it: after the first page view, you eliminate all HTTP requests except the unique page content (say, text and images).

The second rule is exclusively for my favicon.ico file. This cannot be renamed, so it’s unwise to set the expiry to 10 years. But since it’s not a critical component, you can still give it a long shelf-life. I chose 2 months; choose whatever you feel comfortable with.

4. Gzip components

This was easy and effective; it greatly reduced the size of my text-based components. I had to contact my web host and ask them to enable mod_deflate in Apache (mod_deflate is the module that does gzipping). I added this to my .htaccess:

# Gzip all text-based files

SetOutputFilter DEFLATE

Don’t try to gzip images, pdf’s, videos, and so on. These files are already compressed; gzip works for text.

5. Put CSS at the top

Well, duh.

I started with an A for this one. All your own CSS files should be in the .

6. Put JS at the bottom

This is a really interesting rule. At first I rejected it, because I was worried that my javascript might break. Then I tried it, and it worked.

Javascript blocks rendering of the page below, and it also blocks parallel downloads. When the browser encounters javascript, it must download and evaluate it before continuing—in case it performs some critical DOM surgery.

My script does perform DOM surgery, yet it still works fine at the end of the page.

The main problem with putting scripts at the bottom is that you can temporarily get non-working interface items (javascript controls). Until the javascript loads, pressing them will throw a JS error, which may even cause some browsers to crash (i.e., IE).

In my case this wasn’t an issue, because all of my javascript controls are themselves generated by javascript. This creates seamless page enhancement.

7. Avoid CSS expressions

These are nasty proprietary IE things. You shouldn’t be using them at all. An easy A for anyone who follows standards-based methods.

8. Make CSS and JS external

This is a reminder only, and has no effect on your score. Mine were external anyway.

9. Reduce DNS lookups

In other words, avoid contacting other servers to get stuff. An easy A, as I had already transferred items such as google.gif (from Google CSE) to my own server.

10. Minify JS

This one required a little work. I installed YUI compressor and created a batch file. I also used this batch file to combine my javascript files into one file, before compressing it; and I used it to compress my main CSS files too.

11. Avoid redirects

An easy A. No work required.

12. Remove duplicate scripts

Again, no work required. I’d feel a real twit if I lost points on this one.

13. Configure Etags

There’s some debate over this rule. From what I read, Etags can be harmful if you are using a CDN (they can prevent caching of multi-server resources). So disabling them wasn’t really necessary for me; but on the other hand, they don’t seem much use either. So I disabled them in .htaccess:

FileETag none

An overview

Some of these rules were trivial to implement, but some required considerable effort. Also, some rules required thinking, whereas others were no-brainers.

  • The obvious and easy: rules 4, 5, 7, 8, 9, 11, and 12.
  • The easy but not obvious: rules 6 and 13.
  • The easy but not maintenance-free: rule 3.
  • The ones that required some real work: rule 1 and 10
  • The one I fail: rule 2.

Apart from the satisfaction of getting a better score, I have noticed significant improvements in my website’s speed. All these optimisations add up; follow them as far as you reasonably can.

Where next?

So you’ve got your A in Yslow, or a good B at least; you’re top of the class, and now you’re hungry for even more performance improvements. What next?

The 13 rules described above are only the beginning of Yahoo’s full list of rules, which contains 34 rules in total. In the future, Yslow may be updated to include some of these extra rules in its scoring. You might want to look at Yahoo’s video, After Yslow A.

But you have to stop somewhere. Don’t panic if you don’t understand some of these rules, or can’t summon the will or time to implement them. Most webmasters will never achieve Yahoo’s level of website optimisation, and have no need to do so. You don’t need to be perfect to be good.

Finally, the acid test of your website’s responsiveness is to check how it loads on dial-up. Windows users can use Firefox Throttle, an add-on that can simulate a 56k modem connection (be sure to disable “bursting”). Here are some numbers comparing my site (after Yslow tweaking) to IBM, Yahoo, the Websqueeze (just to be cheeky), and Webforumz (*cough*). The first two times are for the homepage on an empty cache, and the third one is for subsequent pages with no new images and a primed cache. Times are in seconds.

Homepage information 56k modem times (simulated) Broadband times
Site Yslow score Text loaded Fully loaded Subsequent text pages Text loaded Fully loaded Subsequent text pages
Badminton Bible 90 (A) 6 16 2 1 2 1
IBM 51 (F) 14 126 Hard to find any! 6 12 Hard to find any!
Yahoo 96 (A) 6 23 Poor samples 1 3 Poor samples
The Web Squeeze 51 (F) 10 54 6 4 7 5
Webforumz 44 (F) 45 64 5 5 6 1

Such numbers fluctuate considerably, and I only took one set of readings. At a different time, the results could look quite different. There are also many other factors at play. Nevertheless, the differences in speed become quite striking when viewed under dial-up constraints. Speed is a competitive advantage!

30 Comments on "Yslow: going from F to A"

  1. evoL says:

    For the CDN thing, I think we can simply use Google Code as a workaround, just like Dean Edwards does on his personal site. Sure, it isn’t a proper CDN, but it’s hosted on Google and they had no complaints about it when asked by Dean. Don’t know if it works out for the score though.

  2. Mike Hopley says:

    It’s certainly possible, but it’s clearly not going to provide the same advantages as commercial CDNs.

    There’s no point using a CDN unless it actually improves the performance of your website. Bear in mind that free hosting, even from Google, may be slower than your paid-for web hosting. It’s no good distributing your files across other servers if those servers turn out to be slow.

    But of course, I just don’t know. You would have to test it to find out.

    If you just want to trick Yslow into giving you a higher score, then see here: http://www.anothercaffeinatedday.com/blog/default/penquin/2008/02/20/Hack-YSlow-to-ignore-CDNs-a-HOWTO-part-deux.html

  3. Mika Tuupola says:

    Amazon is launching pay-as-you go CDN service. It has reasonable prices since you do not need to make a contract. Just pay as much as you use the service.


  4. Mike Hopley says:

    The Amazon service looks interesting. I also came across simple CDN recently, which appears to have a sensible pricing model: http://www.simplecdn.com/.

    Perhaps adopting a CDN is not so unreasonable after all!

    I think I’ll wait and see what Amazon’s offering turns out to be like.

  5. Kane Booker says:

    I totally liked this story, I’m truly waiting to reading more of your threads!

  6. Stanislaw Osinski says:

    Hi Mike,

    Glad to hear that SmartSprites turned out useful in getting an A in YSlow! The dependency on Ant was indeed annoying, so I’ve just released another version that adds the conventional command-line interface. The new version is available as usual from http://smartsprites.osinski.name.

  7. buzzman says:

    Greets! Really amazing. keep working! Tnx! Saw!

  8. Mike Hopley says:


    Great to see those new developments in SmartSprites. It’s an excellent tool, without which CSS spriting would have been abjectly miserable. :)

  9. Dan Kubb says:

    According to Google their AJAX Libraries API project hosts the JS (jQuery, MooTools, etc) on their infrastructure and is a true CDN. I would trust their systems more than any other CDN, including Akamai.

    In my testing, I can download jQuery in about 100ms (on average) from Google’s server.

  10. Mike Hopley says:

    Interesting idea, Dan.

    Advantages: a free and fast CDN for one component, and the browser may already have cached Google’s copy of jquery.js from visiting other websites.

    Disadvantage: adds an extra HTTP request, because you’ll now need two javascript files (Google’s jQuery copy, plus your own JS). Because JS blocks parellel downloads, the browser must wait for the DNS lookup and the download from Google before it does anything else.

    Having said that, the blocking of parallel downloads isn’t an issue when your javascript is at the bottom of the page anyway. So the only real disadvantage is the added HTTP request.

  11. Mike Hopley says:

    I’ve just realised that you can combine ALL your stylesheets into one file — even if they are for different media.

    For example, I have screen and print stylesheets. Instead of using two [link] elements, I can use one [link media="screen, print"]. Inside the stylesheet, I can specify which CSS applies to which media, by using the @media rule:

    @media screen {
    body { font-family: Verdana, Geneva, Arial, sans-serif; }

    /* Rest of the screen stylesheet goes here */


    @media print {
    body { font-family: Georgia, “Times New Roman”, serif; }

    /* Rest of the print stylesheet goes here */


    This saves me one HTTP request (browsers will download print stylesheets). You might want to be careful if using this with handheld styles: that would force handheld devices to download the screen styles, which they might otherwise skip entirely.

    W3C on media types: http://www.w3.org/TR/CSS2/media.html

  12. Mike Hopley says:

    Amazon have released their CDN, called Cloudfront, which should be affordable for any website owner; you only pay for what you use.


    I will definitely be trying it out, when I eventually get time to spend on optimisation.

    I believe they do not (yet) offer Gzipping, so it might be best to keep your javascript and CSS on your own server for now.

  13. Alex Smith says:

    Nice write up, I have been playing with YSlow today to get the best out of my site.

    In terms of CDN’s I use SimpleCDN with their Mirror Buckets to get my site offloaded. I haven’t come up with a perfect (aka in code) method of automaticly loading content from there and instead use .htaccess to push 301 redirect’s to the correct location.

    They also give control over expire, gzip, etag and p3p headers as well – all things that are handy with YSlow :)

    It works great, on average it costs me maybe $1 a week on my site…

  14. Mike Hopley says:

    I just started using SimpleCDN today; it was surprisingly easy! :)

    My Yslow score is now 97. Just a couple of loose ends to tie off, and then I get 100. :D

    As Alex mentioned, SimpleCDN has the significant advantage of allowing you to control expire, gzip, and etag headers. If your CDN does not allow this (e.g. Amazon Cloudfront), then your Yslow score will go down in some areas.

    You can also use their CDN for streaming video.

  15. MikeHopley says:

    A few updates:

    Google Analytics is now available via an asynchronous loader, which allows you to put the script in the [head] without blocking parallel downloads.

    On a related note, there’s a general-purpose loader called LABjs, which looks interesting. I believe Yslow does not yet acknowledge such loaders when calculating your grade.

    It turns out that not all premium CDNs are as expensive as I thought. Highwinds have offered me a one-year arrangement where I pre-pay for $250 worth of bandwidth.

    Conversely, cheap CDNs may not be such a great deal. I paid $200 for SimpleCDN to setup video streaming (resold from Highwinds), and they subsequently withdrew the service. I would have been better off talking to Highwinds directly at the start. Price isn’t everything: dependability matters too!

  16. Shirley says:

    Amazing post, truly!

Got something to say? Go for it!