The content of this article was originally written by Chris Kelly on the New Relic blog.
We spend a fair bit of time improving the performance of our application servers and databases, but truth be told 80% of a web request is spent working on the frontend. The screenshot below shows the entire request time of a large eCommerce site using New Relic. (Shown with their permission, of course.). As you can see, the average total request time is 3.2 seconds but only a fraction (5%) is spent in the web app layer (in purple). The other 95% is spent in the network, DOM processing and page render. So looking at performance from the frontend is critical and that’s what we’re going to do in this post.
YSlow is a tool that helps you analyze the performance of a website based upon 23 best practices. It is available as a browser plugin in Chrome, Firefox, Safari and Opera. It’s also available as a bookmarklet which is ideal for analyzing mobile sites. Or, you can also use it on the command line to process HAR files. The YSlow project is open source and currently maintained by Marcel Duran of Twitter.
The 23 rules that were identified as best practices for Yahoo!’s websites should be considered as guidelines not a strict ruleset. Your website may have different requirements and you should evaluate the rules within your own context. Each rule carries a unique weight, so it will have varying impact on the overall score. You can create a custom ruleset with weights that is better suited to your site. In a follow-up post, we’ll take a look at how to implement your custom configuration with Jenkins to include performance metrics in your build and release cycle.
To get started with YSlow, all you’ll need to do is install one of the browser plugins or the bookmarklet. You can use YSlow on production sites or you can run it against a site running locally. This is perfect to seeing the impact of your changes to your overall score. Run YSlow on any website that you can browse to. Give it a try on some of the big sites like Amazon, Walmart, and ESPN. For this post, I’ll be using the Chrome plugin on cnn.com. Below is a screen shot of the results from the CNN homepage.
The page received an overall grade of D with a calculated score of 68. We’ll take a look at the six rules that received a grade of F to see what could be done differently. Along the way you’ll hopefully pickup a few tips and begin to understand the unique characteristics of your site that may need to be adjusted when running YSlow on your own site.
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.
Use a Content Delivery Network
User proximity to web servers impacts response times. Deploying content across multiple geographically dispersed servers helps users perceive that pages are loading faster.
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.
Adding Expires headers to your static assets permits the browser to keep a local copy of the file and reuse it, which is generally the use case for those assets. Combine this with the hashing filename scheme from above and you have an extremely light payload on subsequent requests without worrying about old assets wreaking havoc on your site. Adding Expires headers is done in your web server configuration. In Apache you’ll use the ExpiresDefault directive and in nginx you’ll use the expires directive in the HttpHeadersModule.
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.
Configure Entity Tags (ETags)
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.
If Expires headers are cache control for static assets, think of ETags as cache control for any URL resource. The general principle is that you never want to generate the same resource twice. By using a gateway cache, which sits between the end user and your application server, you can serve the same resource (e.g., rendered HTML fragment) without the effort or reprocessing the entire request. The general flow is end user requests /foo. The application server generates the response for /foo and fingerprints it with an ETag which is stored with the gateway cache. Thirty seconds later, a second user requests /foo and the gateway server forwards the request to the app server with the ETag. The app server determines that the resource hasn’t changed and sends back a 304: Not Modified response instead of the full resource. Then the gateway cache serves the unmodified content it already has. Good use of ETags not only saves time for your users, it can also save you significant money in the number of requests you can serve from an application server.
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.
We’ve only looked at a handful of the rules that complete the YSlow system. Getting to know each of the rules will give you a strong background on best practices for good web performance. Google also maintains a list of performance best practices which is well worth your time.
In the near future, we’ll be looking at how to customize your YSlow ruleset and integrate it into Jenkins so stay tuned. In the meantime, you should probably deploy New Relic and claim your free Data Nerd tshirt.