I've been playing around with YSlow, the add-on to the FireBug add-on which analyzes web pages and tells you why they're slow based on the rules for high performance web sites, and assigns a letter grade. Basically all the sites I am running through it are getting a C grade so I decided to dig deeper. YSlow uses 13 points to come up with the grade. These rules are as follows:

  1. Make fewer HTTP requests
  2. Use a CDN
  3. Add an Expires header
  4. Gzip components
  5. Put CSS at the top
  6. Move scripts to the bottom
  7. Avoid CSS expressions
  8. Make JS and CSS external
  9. Reduce DNS lookups
  10. Minify JS
  11. Avoid redirects
  12. Remove duplicate scripts
  13. Configure ETags

My blog gets a C grade, ouch, but shouldn't 79 really be C+ or B-? yslow report So How are the grades computed? This is from the docs for YSlow which outlines these rules and give you more tips on what to do to improve your grade.

The grades for individual rules are computed differently depending on the rule. For example, for Rule 1, three external scripts are allowed. For each script above that, four points are deducted from the grade. The code for grading each rule is found in lint.js. The overall grade is a weighted average of the individual grades for each rule. The rules are approximately in order of importance, most important first. The specific weights are in the lintweights array in yslowcontext.js.

Here is the specific array mentioed above with the weights assigned to each rule:

this.lintweights = {
NumComps: 8,
CDN: 6,
Expires: 10,
Gzip: 8,
CssAtTop: 4,
JsAtBottom: 4,
Expression: 3,
ExternalFiles: 4,
Domains: 3,
Obfuscate: 4,
Redirects: 4,
JsTwice: 4,
ETags: 2,

Let's look at why I got some the grades.

Rule #2 Use a CDN

I got a letter of F in rule 2 for not using a CDN. Is Yahoo getting paid to promote Akamai? No but seriously, I doubt any personal blogs are going to start using professional CDNs anytime soon, not unless they are super successful. But if you are using your own personal image cache servers you should add your server host to the list of "known CDNs", because the default CDNs are the ones used by Yahoo! and chances are these are not relevant to your web site. Here's how to add them according to the YSlow docs.

  1. Go to about:config in Firefox. You'll see the current list of preferences.
  2. Right-click in the window and choose New and String to create a new string preference.
  3. Enter extensions.firebug.yslow.cdnHostnames for the preference name.
  4. For the string value, enter the hostname of your CDN, for example, mycdn.com. Do not use quotes. If you have multiple CDN hostnames, separate them with commas.

Rule #3 Add an Expires header

This rule suggests adding Expires tags using the Apache server setttings. According to research at Yahoo they have come up with the 80/20 rule of reducing HTTP traffic.

Since browsers spend 80% of the time fetching external components including scripts, stylesheets and images, reducing the number of HTTP requests has the biggest impact on reducing response time.

These are the complaints YSlow has for my Expires tags.

Here are the docs for using mod_expires. In this environment you can turn on this expires setting in your .htaccess file using these directives:

<IfModule mod_expires.c>
ExpiresActive on
ExpiresByType image/gif "access plus 1 month"
ExpiresByType image/jpeg "access plus 1 month"
ExpiresByType image/png "access plus 1 month"
ExpiresByType text/css "access plus 1 month"
ExpiresByType application/x-javascript "access plus 1 month"

I'm using 1 month expiration dates, but Yahoo is suggesting 10 years. You might want to pick something that suits your specific needs. By its nature having the expires tag should in turn reduce your browser's HTTP requests, thereby improving your score on Rule #1 of Making fewer HTTP requests.

Rule #13 Configure ETags

Another point to touch up on is the Etags required in Rule #13 YSlow is complaining about Etags because of a known problem with the way Etags are written if you have a clustered server network. If your site is served off of one server this ETags score is pretty much useless. Etags is basically a string that Apache slaps on as a response header. By default this string is composed of 3 parts.

  1. The file's last modification date
  2. its current size
  3. its Unix inode

The problem is that with multiple server environments, your inodes are going to be unique and different for each server. So if you have a banner.gif on 12 servers, it will have 12 different Etags, therefore making the whole thing useless. YSlow suggests to remove Etags all together using the directive :

FileETag none

This seems to be the norm for most big portals such as Google and Yahoo these days. This way you not only reduce the complexity, but also reduce the HTTP response headers flying around. If you really want to use Etags you can remove the inode from the Etags string by using this directive which will only use the modified time and size of the file: bash FileETag MTime Size So in my case I have 3 files that have Etags that I have no control over, since they are external stats files and I would think that eventually these people would use YSlow and fix their FileEtag directives accordingly.

Rule #12 Remove duplicate scripts

YSlow noticed that the show_ads.js from Google's AdSense program is loaded twice on this page. I'm currently using the terrific WordPress plugin AdSense Manager which interestingly enough seems to be putting in the JS tag once for each ad on the page. I'm not sure if this is something that might be required by Google. I would be interested in finding out if I can change the plugin to include the AdSense script file only once which would make more "sense" without leading to potential side effects on Google's side of things.