How to Improve Your YSlow Score

When it comes to web performance and speed there are many different scoring tools and tests available to aid you in benchmarking your site. Tools such as WebPageTest, Pingdom, and GTmetrix all provide valuable insights into how fast your site loads and what you can do to make it better. Today we want to explore how to improve your YSlow score and applicable steps you can follow today to speed up your website.

What is YSlow?

YSlow is an open source project and tool that analyzes web pages and helps you figure out why they are slow based on Yahoo!'s rules for high performance websites. It is currently maintained by Marcel Duran, who is also involved in the WebPageTest project. It is important to note that YSlow is rarely being updated anymore. According to GitHub the last commit from Marcel was on March 15th, 2014. However the scores and advice the tool gives you can still be very helpful and when working with clients unfortunately sometimes they do request you improve certain scores. Make sure to also check out our tutorial how to score 100/100 with WordPress and Google PageSpeed Insights.

How it works

YSlow operates in three steps to get its performance test results:

YSlow crawls the DOM to find all components (image, scripts, etc.). YSlow gets information about each component size (Gzip, expire headers, etc.). YSlow takes the data and generates a grade for each rule, which in turn gives you an overall grade.

YSlow rules

YSlow has 23 different rules that it runs your website against to grade it. You can click on one below to skip directly to that section.

How can you check your YSlow score?

GTmetrix offers as easy way to check your YSlow score, which utilizes both PageSpeed and YSlow.

In the YSlow tab you can then check the recommendations and see how you score.

How to improve your YSlow score

Below we will dive into each YSlow rule and explain in a little more detail what each one means and applicable steps you can take to improve your YSlow score.

1. Make fewer HTTP requests

Decreasing the number of components on a page reduces the number of HTTP requests required to render the page, resulting in faster page loads. Some ways to reduce the number of components include: combine files, combine multiple scripts into one script, combine multiple CSS files into one style sheet, and use CSS Sprites and image maps. - YSlow

It is always a good idea to reduce the number of HTTP requests as these can add up to significant load times. Combining multiple scripts into one is also referred to as concatenation. Sometimes this can increase the download time of your file, but it usually outweighs having additional requests. If you are running WordPress you can use a free plugin like Autoptimize. Also make sure to check out our in-depth post on combining external JavaScript and CSS.

However, it is also important to remember that with with HTTP/2 concatenation is no longer as important. Some of these tools like YSlow and GTmetrix have yet to catch up with the new protocols, so always take their recommendations with a grain of salt.

2. Use a content delivery network (CDN)

User proximity to web servers impacts response times. Deploying content across multiple geographically dispersed servers helps users perceive that pages are loading faster. - YSlow

We always recommend using a content delivery network (CDN) to speed up delivery of your assets. You can click into the YSlow options and add CDN hostnames if it doesn't automatically pick it up. For example, we added Google Fonts as this is served from Google's CDN.

Make sure to check out our complete CDN migration guide. You can get KeyCDN up and going on your website within a few minutes! We have a free trial, and it is pay as you go. As you can see from the tests above we scored an A (100/100) with KeyCDN running.

3. Avoid empty src or href

You may expect a browser to do nothing when it encounters an empty image src. However, it is not the case in most browsers. IE makes a request to the directory in which the page is located; Safari, Chrome, Firefox 3 and earlier make a request to the actual page itself. This behavior could possibly corrupt user data, waste server computing cycles generating a page that will never be viewed, and in the worst case, cripple your servers by sending a large amount of unexpected traffic. - YSlow

This is pretty simple to fix. Simply make sure you don't have any sources that are left empty. This is an older rule and we rarely see many people fail this rule.

<img src="">

4. Add expires headers

Web pages are becoming increasingly complex with more scripts, style sheets, images, and Flash on them. A first-time visit to a page may require several HTTP requests to load all the components. By using Expires headers these components become cacheable, which avoids unnecessary HTTP requests on subsequent page views. Expires headers are most often associated with images, but they can and should be used on all page components including scripts, style sheets, and Flash. - YSlow

We are always talking about expires headers on our blog. Check out our in-depth post on how to leverage browser caching and add expires headers in both Nginx and Apache.

5. Compress components with Gzip

Gzip compression allows you to make files smaller thus reducing the amount of time required to transfer a resource from the server to a browser. In today's web environment, many browsers and servers both support Gzip compression. Its ability to reduce file sizes by up to 70% provides a great incentive to make use of this compression method. And brotli compression is also coming around the corner.

Approximately 90% of today's Internet traffic travels through browsers that claim to support Gzip. - YSlow

See our in-depth post on Gzip compression and how to enable it in both Apache and Nginx. Gzip compression is already enabled for all assets delivered via KeyCDN edge servers.

6. Put CSS at top

Moving style sheets to the document HEAD element helps pages appear to load quicker since this allows pages to render progressively. - YSlow

The HTML specification states that style sheets are to be included in the HEAD of the page. However, if you do this it will become render blocking. And while it will fix the warning in YSlow it will actually create one to appear in Google PageSpeed Insights. Completely eliminating the use of render blocking resources may not be possible in all cases. However, there do exist some recommendations to help prevent blocking resources such as lessening the amount of CSS files, inlining your CSS, minifying your CSS, and moving your scripts to the bottom of the page (just before your </body> tag), etc.

In our test, to fix our C grade for this rule we would need to move both our CSS footer style sheets up to the top between our <head></head> tags.

<head> <link href='https://fonts.googleapis.com/css?family=Noto+Serif:400,400italic,700' rel='stylesheet' type='text/css'> </head>

7. Put JavaScript at bottom

JavaScript scripts block parallel downloads; that is, when a script is downloading, the browser will not start any other downloads. To help the page load faster, move scripts to the bottom of the page if they are deferrable. - YSlow

Non-render blocking JavaScript

When it comes to JavaScript there are some best practices to always keep in mind.

Move your scripts to the bottom of the page right before your </body> tag. Use the async or defer directive to avoid render blocking.

Loading JavaScript asynchronously

Async allows the script to be downloaded in the background without blocking. Then, the moment it finishes downloading, rendering is blocked and that script executes. Render resumes when the script has executed.

<script async src="foobar.js"></script>

Deferring JavaScript

The defer directive does the same thing, except it guarantees that scripts execute in the order they were specified on the page. So, some scripts may finish downloading then sit and wait for scripts that downloaded later but appeared before them.

Patrick Sexton has a good example of how to defer loading of JavaScript properly.

Less the amount of JavaScript files (concatenate your JS files into one file) Minify your JavaScript (remove extra spaces, characters, etc) Inline your JavaScript if it is small

Read more about what is blocking the DOM.

8. Avoid CSS expressions

CSS expressions (supported in IE beginning with Version 5) are a powerful, and dangerous, way to dynamically set CSS properties. These expressions are evaluated frequently: when the page is rendered and resized, when the page is scrolled, and even when the user moves the mouse over the page. These frequent evaluations degrade the user experience. - YSlow

CSS expressions can be used to set CSS properties dynamically, like the example below. If you need to change values like this it might be better to combine CSS with some JavaScript to achieve the same thing.

background-color: expression( (new Date()).getHours()%2 ? "#B8D4FF" : "#F08A00" );

9. Make JavaScript and CSS external

Using external JavaScript and CSS files generally produces faster pages because the files are cached by the browser. JavaScript and CSS that are inlined in HTML documents get downloaded each time the HTML document is requested. This reduces the number of HTTP requests but increases the HTML document size. On the other hand, if the JavaScript and CSS are in external files cached by the browser, the HTML document size is reduced without increasing the number of HTTP requests. - YSlow

This rule all depends on the size of your site. Typically smaller sites can inline their JavaScript and CSS which will fix render blocking issues and not create additional HTTP requests. However, this also means the HTML DOC is larger on each page load. So if you are running a bigger site, it might make more sense to to load your JavaScript and CSS from external files, this way you can cache the files.

10. Reduce DNS lookups

The Domain Name System (DNS) maps hostnames to IP addresses, just like phonebooks map people's names to their phone numbers. When you type URL www.yahoo.com into the browser, the browser contacts a DNS resolver that returns the server's IP address. DNS has a cost; typically it takes 20 to 120 milliseconds for it to look up the IP address for a hostname. The browser cannot download anything from the host until the lookup completes. - YSlow

To process of reducing DNS lookups is quite straightforward and can be achieve by adopting either or both of the following suggestions.

Simply reduce the amount of hostnames that are requested in order to generate your web page.

that are requested in order to generate your web page. Download the files that are being referenced to an external resource and host them on your origin server or a CDN. This way, these resources will be retrieved without having to make an additional DNS lookup.

Read our in-depth post on how to reduce DNS lookups.

11. Minify JavaScript and CSS

Minification removes unnecessary characters from a file to reduce its size, thereby improving load times. When a file is minified, comments and unneeded white space characters (space, newline, and tab) are removed. This improves response time since the size of the download files is reduced. YSlow

To minify CSS, JS, and HTML involves removing any unnecessary characters from within a file to help reduce its size and thus make it load faster. Examples of what is removed during file minification includes:

Whitespace characters

Comments

Line breaks

Block delimiters

Check out our in-depth post on how to minify CSS, JS, and HTML.

12. Avoid URL redirects

URL redirects are made using HTTP status codes 301 and 302. They tell the browser to go to another location. Inserting a redirect between the user and the final HTML document delays everything on the page since nothing on the page can be rendered and no components can be downloaded until the HTML document arrives. - YSlow

Basically avoid all 301 and 302 redirects if possible. Obviously when it comes to SEO, this is not always possible. But the less redirects in place, the better. Below is an example of the 301 redirect showing in the HTTP response header. You can always use KeyCDN's HTTP Header Checker tool to see if a 301 is active.

13. Remove duplicate JavaScript and CSS

Duplicate JavaScript and CSS files hurt performance by creating unnecessary HTTP requests (IE only) and wasted JavaScript execution (IE and Firefox). In IE, if an external script is included twice and is not cacheable, it generates two HTTP requests during page loading. Even if the script is cacheable, extra HTTP requests occur when the user reloads the page. In both IE and Firefox, duplicate JavaScript scripts cause wasted time evaluating the same scripts more than once. This redundant script execution happens regardless of whether the script is cacheable. - YSlow

We actually see this happen a lot with with both Google Fonts and Font Awesome scripts, especially with customers running WordPress. Usually a theme developer will include Google Fonts or Font Awesome and then if a user goes and adds the script themselves, or another plugin which utilizes its, the website then has HTTP requests to the same asset. Even with caching make sure you are only including references to your external scripts once.

Entity tags (ETags) are a mechanism web servers and the browser use to determine whether a component in the browser's cache matches one on the origin server. Since ETags are typically constructed using attributes that make them unique to a specific server hosting a site, the tags will not match when a browser gets the original component from one server and later tries to validate that component on a different server. - YSlow

This mechanism helps improve loading times since if the resource can be retrieved from local cache, the browser does not need to make an additional request to the server. A traditional ETag is comprised of three separate components which make it an unique identifier for each resource:

INode

MTime

Size

An example of what an ETag may resemble containing all three components would be similar to 13630e1-b438-524daace96280 . However, this may change in structure depending upon the web server, if the ETag is using strong or weak validation, and if you configure the entity tags (ETags). Check out our in-depth post on how to configure Entity Tags.

15. Make AJAX cacheable

One of AJAX's benefits is it provides instantaneous feedback to the user because it requests information asynchronously from the backend web server. However, using AJAX does not guarantee the user will not wait for the asynchronous JavaScript and XML responses to return. Optimizing AJAX responses is important to improve performance, and making the responses cacheable is the best way to optimize them. - YSlow

The best way to make AJAX cacheable is to take advantage of Expires header or Cache-Control header, as well as the rest of the already mentioned rules below:

Gzip components

Reduce DNS lookups

Minify JavaScript

Avoid redirects

Configure ETags

16. Use GET for AJAX requests

When using the XMLHttpRequest object, the browser implements POST in two steps: (1) send the headers, and (2) send the data. It is better to use GET instead of POST since GET sends the headers and the data together (unless there are many cookies). IE's maximum URL length is 2 KB, so if you are sending more than this amount of data you may not be able to use GET. - YSlow

This is more for developers and most people won't have to worry about this rule, but it is simply stating that it is recommended to use GET instead of POST for AJAX requests. See example function below with jQuery. The xhr parameter contains the XMLHttpRequest object.

$.get(URL,data,function(data,status,xhr),dataType)

17. Reduce the number of DOM elements

A complex page means more bytes to download, and it also means slower DOM access in JavaScript. Reduce the number of DOM elements on the page to improve performance. - YSlow

The DOM is an acronym for Document Object Model. In laymen terms, when you are using a tool like Chrome DevTools, this is showing you a visual representation of the DOM. Your plain HTML is not the DOM, Chrome DevTools shows you the DOM after it has been manipulated, by HTML or JavaScript. You can also think of it as the parsed HTML.

The YSlow rule is telling you to keep these to a minimum. If you are running a CMS might you not have control over this as much as if you are developing a static site. But remember widgets, sections, etc. all could create additional DOM elements. So basically keep your site clean and minimal for the best performance.

18. Avoid HTTP 404 (not found) error

Making an HTTP request and receiving a 404 (Not Found) error is expensive and degrades the user experience. Some sites have helpful 404 messages (for example, "Did you mean ...?"), which may assist the user, but server resources are still wasted. - YSlow

You always want to fix your 404 errors as they can be quite costly over time. Drupal for example has expensive 404 errors. On an average site with an average module load, you can be looking at 60-100 MB of memory being consumed on your server to deliver a 404. Check out our in-depth post on avoiding bad requests.

19. Reduce cookie size

HTTP cookies are used for authentication, personalization, and other purposes. Cookie information is exchanged in the HTTP headers between web servers and the browser, so keeping the cookie size small minimizes the impact on response time. - YSlow

Keeping your cookie sizes small might not be as important as it used to be but it is something you should always check, especially if you are a developer. Some additional tips are:

Eliminate unnecessary cookies

Be mindful of setting cookies at the appropriate domain level so other subdomains are not affected

Set an Expires date appropriately.

20. Use cookie-free domains

When the browser requests a static image and sends cookies with the request, the server ignores the cookies. These cookies are unnecessary network traffic. To workaround this problem, make sure that static components are requested with cookie-free requests by creating a subdomain and hosting them there. - YSlow

Although cookies are very useful in some cases, in other cases, such as the delivery of static content, they can hinder performance. When a browser makes a request for a static asset such as an image or CSS file, there is no need for it to also send a cookie to the server. This only creates additional network traffic and since the files are static (they do not change) the server has no use for the added cookie.

When you use cookie-free domains you are able to separate the content that doesn't require cookies from the content that does. This helps improve your site's performance by elimination unneeded network traffic. Read our in-depth post on how to use cookie-free domains.

21. Avoid AlphaImageLoader filter

The IE-proprietary AlphaImageLoader filter attempts to fix a problem with semi-transparent true color PNG files in IE versions less than Version 7. However, this filter blocks rendering and freezes the browser while the image is being downloaded. Additionally, it increases memory consumption. The problem is further multiplied because it is applied per element, not per image. - YSlow

If you are still developing for browsers prior to IE7, well, we've got another problem. Most can ignore this rule as it should not longer be an issue.

22. Do not scale images in HTML

Web page designers sometimes set image dimensions by using the width and height attributes of the HTML image element. Avoid doing this since it can result in images being larger than needed. For example, if your page requires image myimg.jpg which has dimensions 240x720 but displays it with dimensions 120x360 using the width and height attributes, then the browser will download an image that is larger than necessary. - YSlow

For the best performance, you should always upload your images at scale if possible. For example, if you have an image that you want to display at 200 px wide, don't upload an image that is 400 px wide and then scale it with HTML. A better way to accomplish this is to use the srcset attribute in the <img> tag which allows you to define possible resolutions that the browser can choose from. Here an example:

<img srcset="/img/keycdn-300.jpg 300w, /img/keycdn-600.jpg 600w, /img/keycdn-1200.jpg 1200w" src="/img/keycdn-600.jpg" alt="KeyCDN">

Most modern web browsers support srcset, except IE and opera mini.

23. Make favicon small and cacheable

A favicon is an icon associated with a web page; this icon resides in the favicon.ico file in the server's root. Since the browser requests this file, it needs to be present; if it is missing, the browser returns a 404 error (see "Avoid HTTP 404 (Not Found) error" above). Since favicon.ico resides in the server's root, each time the browser requests this file, the cookies for the server's root are sent. Making the favicon small and reducing the cookie size for the server's root cookies improves performance for retrieving the favicon. Making favicon.ico cacheable avoids frequent requests for it. - YSlow

It is recommended to keep your favicon as small as possible and make sure it isn't generating a 404 request. For example, if we take a look at Google's favicon we can see that it is very small at only 1.6 KB.

And it is also using the Cache-Control header.

Summary

As you can see there are a lot optimizations you can make to your website to improve your YSlow score. Our best advice is to simply implement as many optimizations as you can in your individual environment. Remember that the score is just a number, don't forget about perceived performance, specifically the user's experience. Just because a tool says your site loads fast, it could be the exact opposite experience for an actual person browsing your site.

Do you have any other recommendations to improve your YSlow score? If so let us know what they are below.