Typical conversations about Web performance tend to revolve around client/server latency, database performance, and the time it takes a server to render and send HTML to the client.
- Request minimal data
- Request fewer times
- Compressing (minimize data)
- Caching (minimize requests)
- Merging (minimize data & requests)
- (CDN) Hosting (minimize requests)
Asset compression can be achieved by using a server plug-in for gzip or deflate compression. While sending fewer bytes across the wire is a benefit, the extra CPU time spent processing the data on both the server and client end may offset the gain. Certain settings can be tweaked to achieve the best results, but the inconsistencies of browsers become problematic and some architects are arguing against this practice — calling it an unnecessary resource hog (Cal Henderson/Flickr).
Caching can be further enhanced by configuring the response headers for requested assets. Instead of downloading an asset that has not recently changed, a host server sends a header-expires entity that directs the user agent to use a cached version of an asset, which is set to expire in the distance future. Images usually do not get updated very often, so why request them over and over? Specifying both "cache-control" and "expires" should handle HTTP 1.0 and 1.1 protocols. A typical response header, shortened to show only caching information, might look like this:
Date: Tue, 17 Apr 2007 18:39:57 GMT
Expires: Fri, 14 Apr 2017 18:39:57 GMT
Last-Modified: Mon, 16 Apr 2007 23:39:48 GMT
A Cacheability Engine can test the data on a particular site. The engine gives you a detailed analysis of the different objects and how they are being cached. Based on the results, you can tweak parameters for the various objects to attain optimal performance.
The browser's default limitation of two concurrent HTTP requests from the same domain at any time is a rendering bottleneck. Reducing the number of requests can decrease the time needed to render a page. Concatenating client side HTTP resources can also address this particular issue.
[img_assist|nid=3375|title=|desc=|link=none|align=right|width=250|height=209]A popular technique for reducing HTTP requests for large image sets is CSS sprites, a relatively new concept that allows style sheets to manage the partial visibility of a single large image that also contains other related images. Sprites were originally used in the early years of the computer gaming industry, when bandwidth conscious game designers laid out all the game graphics in "sprites," one large image that contains many smaller images. The game engine then displayed one part of the image while masking out the rest, requiring only one image to be loaded into memory.
The same can be applied in CSS, where selector attributes can be used to show and hide parts of an image, as needed. This technique is effective in reducing HTTP requests for such common interface functions as image-based button roll-overs and other components that require several images to preload and be ready on an event trigger.
For example, many multi-national companies have Web sites with landing page maps. These interaction models usually involve roll-over states for various countries — a task that is usually suited for image maps or Flash. With the advent of CSS sprites, this type of functionality can once again be built using DHTML, thus providing a more efficient, semantic, accessible, and search friendly user experience. Consider the recent redesign for Intermec — the world leader in manufacturing RFID based technologies. The map itself takes up a significant portion of page real estate. As the user rolls over the text links for language options, the corresponding country lights up on the map. With twelve countries that need a highlighted state for the same map, this poses a problem. Fortunately with CSS sprites, a single HTTP request with an image that contains roll-over states for all the countries involved can be made.
Essentially, CSS displays a region of an image and masks the rest, using a combination of attribute positioning and hidden overflow. In the case of the Intermec map, the 456px by 705px sprite GIF image has three components:
- The top map is the default view on page load.
- The second and third maps have highlight states for various countries.
The key is to spread the countries around so that no two countries are sharing the same rectangular coordinate space. Intermec used only two additional repetitions of the map. The target's CSS selector has three sets of attributes that define the masking region:
- Left and top sets the position of the viewing area to the correct country on the default top map.
- Height and width sets the viewing area's height and width.
- Background-position slides the image to the correct position, showing the roll-over state in the viewing area created by the first two masking region attributes.
-moz-opacity:0; opacity:0; filter:alpha(opacity=0);
In other words, two HTML elements have the same image sprite set as a background, the first showing the entire map of the world, while the second is masked to show only the roll-over state for the country in consideration. In this fashion, roll-over states for any number of countries can be created with a single HTTP image request by stacking masked versions of the same image — one on top of another.
CDNs (Content Delivery Networks) have recently been used to reduce the processing and bandwidth requirements of hosted Web applications while increasing performance by distributing resources across server networks. Proximity to these Web resources directly translates into increased performance.
Some companies, such as Akamai, have built their businesses around providing these networks for many large scale Web operations to serve their content. Akamai's pricing structure is based on the total KB weight of Web pages served, times the number of user requests. Improvements in Web performance can affect the bottom line in a very direct way. For example, one of AA|RF's high profile clients pays approximately $8000 per month for a 320KB homepage. If a presentation layer developer were to implement performance enhancing techniques that reduce total page weight by 25 percent, the client stands to save $2000 per month. Remember we are talking about just the homepage in this example. The development time quickly pays for itself!
[img_assist|nid=3377|title=|desc=AA|link=none|align=right|width=250|height=318]Yahoo! recently started serving their YUI (Yahoo! User Interface) libraries from their own world-wide server farm — for free! The new service provides:
- gzip compression (reduced file sizes range from 60% to 90%);
- Quality cache control, with distance future header expiration.
- Geography-based file serving from edge computing systems.
Just as HTTP requests can affect the time it takes to render a Web page, so can the combined weight of assets affect performance. Employing efficient, semantic, and architecturally well-designed, client-side programming techniques can help keep file sizes down to a minimum.
Although many of the enhancements techniques described in this paper seem to save only a few kilobytes of page weight, the overall net improvement can make a big difference. The importance of adopting these techniques is especially relevant for high traffic Web sites that receive bandwidth intensive usage statistics.
- YUI: Performance Research, Part 1
- YUI: Performance Research, Part 2
- YUI: Free Hosting of YUI Files from Yahoo!
- W3C Header Field Definitions