How to Speed Up Your Site and Get a YSlow Grade A

August 12th, 2009

When I first launched my homepage it earned a Grade F in Yahoo’s YSlow. This post explains how I decreased load time and achieved a Grade A.

If you’re not familiar with it, YSlow is a Firefox Add-On that integrates with the indispensible Firebug. It measures page performance and provides suggestions on how to make improvements.

The key to improving the speed of you page is to not only reduce the amount of data that is sent to the client, but also the number of requests made to the server. Each time your browser makes an HTTP request from the server, time is wasted setting up a connection and waiting for a response, introducing further delays.

Originally, my homepage and all its assets – images, JavaScript and CSS files – weighed in at 196kb with a total of 46 HTTP requests. It’s now down to 75kb with 16 requests and loads in half the time.

So here’s how you can improve your YSlow grade…

Compress Images

Saved me 18kb
You probably already know you can reduce image filesizes by choosing the optimal file format and saving at the right quality level. What you might not know is that the resultant images can often been compressed further without any loss of quality.

Smush.it is a lossless compression tool (now built into YSlow itself), which in a single click checks your site for any bloated images, compresses them and then pops them all in a handy zip file for you to download.

You’ll find Smush.it under the Tools menu in YSlow.

Remove 404s

Saved me 4kb and 2 HTTP requests
Check Firebug’s Net tab for any red items, these are files which cannot be found. Here you’re wasting an HTTP request and downloading a 404 page you don’t need. I was surprised to see that I actually had a couple 404s from a Lytebox CSS file.

Remove unused CSS

Saved me 1kb
Firefox add-on Dust-Me Selectors checks your pages for any CSS selectors which are declared in your CSS but not used by your HTML. Providing these aren’t used in any other pages, these can be removed to save bytes.

Combine JavaScript and CSS files

Saved me 4 HTTP requests
If each of your pages use the same few JavaScript files, try combining them into a single file to remove unnecessary HTTP requests. You can do the same with your CSS files.

Minify JavaScript and CSS

Saved me 15kb
Hopefully you write your CSS and JavaScript to be easy to read and maintain, with plenty of comments, verbose variable names and appropriate use of whitespace. However none of this is of any interest to browsers, so these can all be stripped out by a JavaScript minifier, saving crucial bytes.

Use the JavaScript Compressorator to see how much you can save.
There are a few CSS minifiers around, but I’ve found Robson’s CSS Compressor to give the best results.

Be sure to keep the original uncompressed files for any further development. Name the minified file *.min.js or *.min.css and repoint your HTML files.

Gzip Components

Saved me 53kb
Gzipping your text-based assets (HTML, JavaScript and CSS) allows your webserver to transmit compressed versions of your files, often reducing the filesize by around 70%, and allow the users’ browser to seamlessly unzip it and process it as normal. This is probably the quickest and most effective way to improve your site’s performance.

How you turn on gzip compression depends on what webserver you’re running. If it’s Apache 2, as is most common, then the easiest method it to add the following to your .htaccess file:

AddOutputFilterByType DEFLATE text/html text/plain text/xml application/xhtml+xml
AddOutputFilterByType DEFLATE application/x-javascript application/javascript text/javascript text/css

If you’ve not got a .htacess file, simply add a text file called ‘.htaccess’ at the root level of your site containing the above text.

To confirm your files are being gzipped, use Firebug to inspect your headers and look for ‘content encoding: gzip‘.

Create CSS Sprites

Saved 14kb and 8 HTTP requests
Images on a website can often be the biggest abuser of HTTP requests. CSS sprites are a technique to reduce the number of requests necessary by combining multiple images into a single image and then using CSS’s background-position to position them.

To the user, everything looks the same, just a little bit faster.

This can also trim down the filesize a fair bit, especially if you combine images of the same format with similar colours. For instance the images accompanying the links in the sidebar to the right are from a 3kb CSS sprite, but individually the images totalled 11kb.

Use multiple Subdomains

The HTTP specification states that a browser can only download a maximum of 2 files from each domain at any one time. If all your files are on a single domain then your users will waste time queuing up downloads.

So once you’ve reduced your HTTP requests, try spreading them around. I’ve moved my JavaScript, CSS and image files onto separate subdomains allowing the user to make the most of their bandwidth.

Add Expires Header

YSlow suggests that you ‘Add Expires headers’, which basically is a note in the header telling the browser to cache the file until a specific date. It won’t then waste time looking to see if the file has changed until that date.

To implement a long expire header, add the following code to your .htaccess file:

<FilesMatch ".(ico|pdf|flv|jpg|jpeg|png|gif|js|css|swf)$">
        ExpiresActive On
        ExpiresDefault "access plus 1 year"
</FilesMatch>

This does however complicate maintenance. If you make a change to any of the affected files you’ll need to give it a new filename to prevent the cached version being used. I tend to put the last-modified date in the filename to avoid this.

Configure Entity Tags

Entity tags are used to check if the file in your cache is the same as the one on the server. Yahoo’s problem with them is that this doesn’t work if the site is server from a different server – as might happen on a load-balanced site.

So for most of us, this isn’t really a problem that needs solving. If you want to keep YSlow happy though, you just need to add the following to your .htaccess file:

FileETag none

Image Replacement

Saved 17kb and 12 HTTP requests
Due to limited font support across the web, people often use images to display custom fonts. Along with the accessibility issues this presents, this also has the effect of increasing your page’s footprint.

A more accessible and maintainable solution is to use an image replacement technique such as sIFR, FLIR or Cofun to replicate a font.

I prefer Cufon for a variety of reasons, not least because it’s a purely JavaScript technique meaning it can be nicely minified, combined and compressed. The Cufon script and the JavaScript-encoded font used on this site come to around 12k – far less than the images they replaced and didn’t cost any extra HTTP requests.

Prioritised Loading

Once you’ve completed all the above steps, you can still make your website appear to load quicker.

Placing CSS at the top of the page allows pages to be displayed progressively as it loads.
Place JavaScript at the bottom as it blocks the download of any other content.

Backend Optimisation

As well as improving the speed your content is transmitted, you can improve the speed it is generated. On anything but the most basic static HTML site, there will be some server-side programming and database access slowing down the delivery of your content. Be sure you don’t overlook any opportunities for optimisation here.

If you’re not a backend developer there are still opportunities for improvement, for example by installing a caching plug-in on WordPress.

Conclusion

I completed all the above steps mainly as a learning exercise and because I can’t resist the allure of getting a top grade in anything! However, some of the above ‘solutions’ aren’t necessarily appropriate for every site – it’s up to you to assess how great the potential performance gains are and if they worth the overhead in maintenance.

7 Responses to “How to Speed Up Your Site and Get a YSlow Grade A”

  1. [...] This post was Twitted by pflynny [...]

  2. What if you’re not using Apache but an IIS server, what are the alternatives to all of your htaccess tips?

  3. To be quite honest, I’ve not got enough experience of IIS to answer that. Hopefully someone else can advise?

  4. Matt says:

    Usual post man, I’ve been reworking my own personal site and YSlow tore me a new one. Got a “D” on YSlow V2 profile, and a “C” on the blog or small site profile. My new generation design 9not up as of now) is currently an A”, with a score of 92, it took a fair amount of work. The most work was in using image maps and sprites where sensible, combining CSS & JS & then minifying them to reduce size and HTTP requests, but seeing that “A” in YSlow feels good :P

    One other thing I discovered is because I’m on a Litespeed server, not Apache, the ExpiresDefault requires the to either A (access) or M (modified), and then the time in number of seconds. It didn’t like the access plud time format at all. So I ended up with something like this (3888000 = 45 days);

    ExpiresActive On
    ExpiresDefault A300
    ExpiresByType text/css A3888000
    ExpiresByType application/x-javascript A3888000
    ExpiresByType image/gif A3888000
    ExpiresByType image/jpeg A3888000
    ExpiresByType image/png A3888000

  5. for IIS you could use ISAPI rewrite (I may have spelled that wrong) the latest version can use the same directives as Apache.

    great writeup by the way, found a few things that helped out. I’m actually here cause i found a 404 in my firebug net panel that I can’t track down for the life of me, somehow I’m loading my images directory … I don’t have that anywhere in my template though so it must be a plugin… it’s driving me nuts… any advice on how to track down where the 404s are coming from ? I tried headers, but no luck there either.

    brent
    @
    mimoYmima.com

  6. Dave Harris says:

    @Brent

    You’ve probably fixed that problem some time ago but just in case – and for anyone else with a similar problem…

    You’re using WordPress.

    I’d guess you have changed the permalink setup and not updated the .htaccess file. WordPress uses that to rewrite things which otherwise look like you’re accessing a directory. Also, check that your DNS setup matches your virutal server setup – e.g. that both say http://www.yourdomain.com, or there’s a ServerAlias command for the site & Base URLs in the General setup. for example.

    BTW I’m assuming you’re using Apache as the webserver but similar considerations apply for others..

  7. MIck says:

    Well this is the first in a long line of sites that actually gives directions on what to do.
    There was no way I could figure out where to put the expires tag. Most sites would say to add it, but never where.

    Thanks for the clear information…..

    I’m still trying to work out why GZIP won’t work. Yes, I’m on Apache 2.0 (I’ll fiddle with the .htaccess a bit more).
    Cheers

    Thanks again.

Add a comment