Use of CSS sprites is an advanced HTML technique that can be a little controversial – at least in terms of questioning whether any potential performance benefits merits the effort in implementing them. I don’t want to cover the mechanics of how you implement them in this article as the appropriate Google search will throw up lots of suitable tutorials and advice on this, and I see little benefit in repeating such content here. However, what I do want to discuss in a little more detail are some of the reasons for using these in terms of performance.
phpBB is a popular, rich featured and robust Open Source forum engine, and this is the one that we’ve chosen to use on the OpenOffice.org forums that I maintain and administer. Unfortunately, the phpBB developers don’t appear to have scalable performance as a primary design goal, and their (lack of) use of CCS sprites is one example of this. I’ve taken an analysis of a week’s Apache access logs for all forums, and I want to use these to help explain a few points.
Our forums are regularly indexed by just about every search engine going, and almost exactly 50% of page requests are from the search engine robots. These are somewhat of a special case in that search engines will typically only download the HTML content of the various forum topics as they’ve already cached any static image content; hence we typically get one HTTP request per page (for the HTML document itself) for these. On the other hand, users viewing the site with interactive browsers such as MSIE or Firefox are a quite distinct class, as the users’ browsers do require the page furniture (the GIF and PNG images for buttons and other graphics; the CSS to layout the page; etc.) for these cases.
I already have the HTTP caching parameters tuned so that regular users cache such furniture locally and this improves both response and server load fulfilling their page requests. However a large percentage of page hits (the majority) are from guests who are typically using a search engine to seek help on some specific OpenOffice.org issue and are being directed to a specific topic on our user forums. Such accesses are rarely pre-cached on their browsers, so our server must fulfil all HTTP requests. I therefore see the following typical breakdown of GET requests in aggregate:
- 14% php page requests by bots
- 14% php page by user browsers
- 9% CSS style sheets
- 60% GIF, PNG and JPG furniture
- 3% Site ICO file
The rest of the requests are trivial (<0.2%), but the bulk of the image furniture is used with the styling to present the pages. It is this 60% that would be reduced by a factor of five or so if phpBB used CSS sprites to render this furniture. The aggregate image related traffic is typically reduced by some 50%, but the impact on performance is best shown with reference to the figure to the right. Displaying a single phpBB page can result in the browser downloading over 40 individual components. Some 30 of these are image furniture. OK, these can be locally cached depending on browser settings, but this histogram gives that actual percentage of request in buckets according to the number of requests per page averaged across all forums for a typical week The left bar corresponds to the bot requests which are singletons. Most page requests generate 30-49 separate component requests from the guests browsers that haven’t cached furniture. The block in the 2-19 range are the subsequent accesses where the furniture is already cached.
As I discussed in my earlier article, Performance Collapse in Systems, having this pattern of burst requests impacts both scaling robustness and throughput of any service system such as Apache. OK, the HTTP 1.1 protocol enables such requests to be marshalled into single request packets, but in a typical LAMP configuration, Apache still deals out such requests to its farm of child processes. Even where the file requests are a conditional load based on an Etag, the individual child processes still need to validate the file timestamps. Apache accomodates such bursty input by creating extra child processes, which it then culls back in quiescent periods (unless the Apache administrator has configured the “low water mark” number of processes to prevent excessive child process churn, and doing this requires allocating a lot of memory to Apache.) So having a lot of image furniture on each page is bad news in terms of both Apache performance and therefore server load, as well of course as user response. Use of CSS sprites moves the bulk of this presentational complexity to individual client browsers where the local processing is available.
I’ve now migrated my blog bullet icons to sprites, and with this my Page Speed score is now 99/100. Missing that last 1/100 is a bit of a pisser, but quite honestly the “mild” suggestions that are given aren’t worth a damn in real performance terms – even Google’s own home page only scores 99/100. As a comparison, one of my favourite blogs, the Virology Blog, uses the WordPress engine, and this scores 84/100.