Yahoo! released YSlow, a Firefox extension that integrates with the popular Firebug tool. YSlow was originally developed as an internal tool at Yahoo! with the help of Steve Souders, Chief Performance at Yahoo! and author of O'Reilly's High Performance Websites book.

YSlow analyzes the front-end performance of your website and tells you why it might be slow. For each component of a page (images, scripts, stylesheets) it checks its size, whether it was gzipped, the Expires-header, the ETag-header, etc. YSlow takes all this information into account and computes a performance grade for the page you are analyzing.

The current YSlow score for the drupal.org front page is 74 (C). YSlow suggests that we reduce the number of CSS background images using CSS sprites, that we use a Content Delivery Network (CDN) like Akamai for delivering static files, and identifies an Apache configuration issue that affects the Entity Tags or ETags of static files. The problem is that, by default, Apache constructs ETags using attributes that make them unique to a specific server. A stock Apache embeds inode numbers in the ETag which dramatically reduces the odds of the validity test succeeding on web sites with multiple servers; the ETags won't match when a browser gets the original component from server A and later tries to validate that component on server B.

Here are some other YSlow scores (higher is better):

From what I have seen, Apache configuration issues, and not CMS implementation issues, are the main source of low YSlow scores. Be careful not to draw incorrect conclusions from these numbers; they are often not representative for the CMS software itself.

And it doesn't change the fact that drupal.org is currently a lot slower than most of these other sites. That is explained by drupal.org's poor back-end performance, and not by the front-end performance as measured by YSlow. (We're working on adding a second database server to drupal.org.)


Jacques (not verified):

What is more interesting is that the Drupal.org site score is a lot better than my Drupal-based sites.

More reason to turn on CSS and JS compression, which are currently off on my sites.

Chris Johnson (not verified):

We're running YSlow against our large 4.7 platform (~77 contrib modules, ~1/2 million lines of code, 100+ sites/instances) and it looks like ETags, CSS and JS are the most obvious problems.

Unfortunately, Drupal makes it impossible to move the CSS and JS bits to the proper places in the load sequence to get most of the performance gains available there. Many other Drupal features are implemented in a way that is not scalable to large, enterprise installs.

Cheaper, faster hardware has been masking the problem for too long. For both drupal.org and for us, bad performance is now a critical problem.


Compared to Drupal 4.7, Drupal 5 supports CSS aggregation, and Drupal 6 will also support JS aggregation. That reduces the number of HEAD/GET requests per page, and should translate to better front-end performance and higher YSlow scores.

As for the ETags problem, my tests showed that this affects static files served by Apache, and not dynamic content generated by Drupal (see original screenshot). Maybe that is different in Drupal 4.7 -- I only tested YSlow against Drupal 5 sites? As far as I can see, there is no ETags problem to fix in Drupal itself.

I'm not sure I understand what you mean with "Drupal makes it impossible to move the CSS and JS bits to the proper places in the load sequence". All Drupal modules register their CSS and JS files, and it is the Drupal theme (the page template) that decides where and when to output the HTML import statements. There shouldn't be any restrictions here, but maybe I missed your point?

Making it easier to scale Drupal sites is an ongoing task, typically driven by the people that push Drupal to its limits. As soon I have some more time, I'd love to focus on this more. In the mean time, I'd love to hear more about your ideas and suggestions.

Chris Johnson (not verified):

I think the ETags situation is more a matter of our configuration, rather than Drupal. I didn't mean to imply that the ETags problem was related to Drupal core code. Rather, I just mentioned the biggest 3 trouble areas we saw when we ran YSlow on our sites.

As for the load sequence remark: pages are perceived to load faster when as much JS is pushed to the end of the page as possible. The browser can start rendering the page and the user can start to read it, before all the JS is downloaded. But the phptemplate theme engine, at least, aggregates a bunch of the JS links into the $head variable (from drupal_get_html_head()). There doesn't appear to be any easy way to segregate those JS pieces to the end of the page in page.tpl.php.

I could be mistaken, of course. But regardless, it would make more semantic sense and provide better control and re-usability to not aggregate different types into $head, that is, items which *must* be there and items which *can* be there, but could be elsewhere.

I'm glad to learn that Drupal 5 aggregates CSS and that Drupal 6 aggregates JS. Although, be careful, because some JS needs to be present before the page can be rendered correctly, and other JS can come later. It's be nice to be able to segregate those two. There may be other functional divisions, too -- I'm not a client-side JS expert!

Christoph C. Cemper (not verified):

I ran YSlow on a Drupal site of mine (located in a DC in Texas for US traffic) and got other grades than you did.

  • F for EXPIRES HEADER on CSS files
  • F for GZIPs missing on CSS, JS files again

Overall the Drupal 5.1 site had a performance grade of F (42) ... which is way worse than your sample.



That looks like an Apache configuration issue: CSS and JS files are served by Apache, not by Drupal.

Paul K Egell-Johnsen (not verified):

I get a grade of 81.

Added the javascript_aggregator module (remember to paste in some code into page.tpl.php file).

I'm also using the Boost module.

In the .htaccess file I added this to the bottom of the file:

<IfModule mod_deflate.c>
AddOutputFilterByType DEFLATE text/html text/plain text/xml application/javascript text/css text/ecmascript text/javascript application/ecmascript

FileETag none

In the IfModule mod_expires.c I changed the line ExpiresByType etc to:

ExpiresByType text/html A10

After this there are a few files which won't gzip (notably the googleanalytics urchin.js file (local version set in the module) and the downloattracker.js file from google_analytics module).

You can not control expires headers for external files (some google tracking stuff I use).

The javascript_aggregator doesn't seem to do its job good enough in the minify (it says it will remove /* */ comments, but they do exist in the cached aggregated files...). It could, hopefully remove other comments, and extra whitespace in the future...

Reduce DNS lookups is a two egged sword. If you reduce them too much, your parallelity will suffer. Since I get pictures from flickr.com I get a B on this point.

Hope this will be of help to people.

Anonymous (not verified):

At the moment I have a site which scores 84 for authenticated users, and 88 for non-authenticated users.

For authenticated users there are 2 elements beyond my control, namely the compression of google js and working with a CDN.

The part that mystifies me though is that the site only fails the DOM test for non-authenticated users.

I wonder if anyone out there could point me in the right direction, or offer insight as to why this may be. As I understand it, these DOM elements are mostly controlled by the complexity of the theme. If that is the case, why the fail for authenticated users if they are viewing the same theme?

Tom (not verified):

I like the tool, but it still baffles me how come on my test site, I can't get better than an F on Expires headers. I have mod_expires on, and .htaccess is correctly done, but I still have 32 files without expire dates. I'm assuming that's not normal since the drupal.org shows none.