Maybe I haven’t been paying close enough attention, but over the past few years an interesting variation of CSS Sprites has been getting a lot of play on large web sites that serve millions of users.
I stumbled over one of these on Amazon and posted an image here last week, but the comments quickly pointed out that this was far from a unique case. Google, Yahoo, and Apple are also doing similar, and those are just the ones I’ve found so far. Yahoo even documents the practice on their Developer Network and the Flickr code blog.
The problem is making a site with multiple UI elements load quickly. There’s a lot of overhead if your design requires dozens of UI images and icons and the like. File size isn’t the only factor, each image is called with a separate HTTP request, and the more of those you have the longer your site takes to load. At Yahoo and Google traffic levels, it’s vitally important to think about how many million users a day a site is losing to long load times.
The solution? Cram as many UI images as possible into a single image, then use selective CSS to clip and only show the relevant part of the image:
Andy King has written up a great how-to guide on implementing sprites this way. He does warn that the method isn’t without its issues — some devices (the iPhone being the most notable) apply the sprites in a memory-intensive way that slows the device to a crawl.
I also wonder about the pop-in effect; when your entire UI is in one or two larger images that take a second or so to load, the site will render without images for that brief time then pop in all the images at once. This reminds me a bit of the FOUC of old, but in a slightly less jarring way. Probably a necessary evil in this case.
But the question I’ve had on my mind is whether I should start doing this myself. Should all the sites I build use Sprites this way from now on?
I’ve started playing around with this all-in-one approach for UI images, and I’m finding it quick going and fairly simple to do. From Photoshop, I crop my source images and prepare to save, but rather than export to a JPG / GIF / PNG I’ll instead take a flattened version of each image and place it in a new document that becomes the master, saving out the entire thing to an optimized image. (And if I go with PNG, it’s worth also running a non-Adobe PNG compression tool against it, something like Pngcrush or PngThing.)
Planning for repeating images is a bit trickier, but I think the MobileMe example serves as a guide. Have one image per row, leave room between each, and have the repeating bits span the entire master image width rather than the smaller 1 pixel strip you might traditionally have saved out. The extra overhead will compress fairly well, and it seems fairly certain that the fewer HTTP requests will more than make up for it.
So, back to the question at hand, should I be building sites this way? I think the answer is: sort of, yes.
It does require more work. Applying the section of the master sprite image you want to show up takes time. And you really need to carefully plan out that master sprite image to ensure the wrong slice doesn’t show through on text-resize or in unplanned text wrapping situations. I don’t see every site benefitting enough to justify the time overhead.
Of course, the maintenance is also easier; need to change the colour of a UI element? Just edit the master and re-save one image. Done. Need to add more images? Make the master a little larger and drop ‘em in. Done.
Web applications where a quick-loading and responsive UI are essential seem like the perfect fit. Sites with a common set of design elements that are used globally across the site might also benefit.
But I doubt most sites will require you to go as far as the every-image-in-one like the MobileMe example; a lighter approach of, say, combining all the icons into one image file like Yahoo is likely good enough most of the time. And simple wins like taking a box with rounded corners which traditionally would have been three separate images (one for the top, repeating middle, and bottom) and combining those three into one is fairly trivial to pull off.
The main change I expect is that I’ll likely look for ways of reducing the overall number of images I save out for each site in the future. If I can see a quick way of combining a half dozen into one, I’ll do it. If I can’t, oh well. If I end up with 12 images instead of 20, that’s probably optimized enough for the majority of sites I’ll build.