Preload your CSS Images

Here’s something I come across occasionally that I find rather annoying.

You’re browsing around the web at 2am, searching for the perfect gift for that special someone. You mouse over the tab navigation and.. WTF… the tab completely disappears for a second. After another round-trip to the server, the on-hover image for the tab finally loads displays as it was intended.

Sometimes this isn’t a big deal, since it’s only a 200ms round-trip to the server for a tiny image, but occasionally on a high-traffic server, or a site that has quite a bit of latency, it creates a noticeable eyesore, and to me, it seems flat out lazy when there’s easy ways of avoiding it, such as:

1. Image Sprites

Sprites are becoming more and more common these days. The basic idea of an image sprite is that you combine many small images into a single large image and use CSS to manipulate the position of the image so only the desired section shows up where needed. For example, to get the hover state image for the undo icon, they would have to set the background-position to -200px  -40px (200px from the left, 40px from the top of the image sprite).

sprite_ex

Instead of the client having to download 7 icons that display on a page, the use of a sprite collapses 7 HTTP GET requests into a single request, albeit one that takes slightly longer due to the large image size. Take a look at the sprite as it’s used in the Stack Overflow Markdown editor.

sofia1

With a bit of context, you can see that the 3 rows represent the regular, disabled, and hover states, respectively from top to bottom, for each icon. They’ve reduced 39 requests to a single 4Kb byte request. This saves a substantial amount of time in setting up and tearing down TCP connections, and it’s fewer hits for your webserver to service, so everybody wins. There are  some good sprite generators around the web, which takes almost all of the hard work out of the equation for you.

2. Preload page images with JavaScript

This one is not quite as elegant, but it’s still used quite a bit, and can be a reasonable solution to a one-off problem.

When I had to build an online portfolio for my Technical Writing class at MSUM, I was required to add links to three tools that I use on a regular basis. I wanted to dazzle a bit, so I took screenshots of the three sites I chose, and used LightBox to load larger, high-quality screenshots.

Logically, the user is going to scan the first paragraph, then move to the first section and start scanning. My guess was at that point, they’d be bored and would click on the image to see a larger version. But in the meantime, enough time has probably elapsed to have downloaded all 3 high-quality versions, so why not make the browser download them in the meantime? Easy.

var imgs = ["images/kuler_large.jpg", "images/reddit_large.jpg", "images/mdc_large.jpg", "images/wikimedia_large.jpg"];
for (i in imgs){
    var newimg = new Image();
    newimg.src = imgs[i];
}


3. Make jQuery do everything for you

jQuery is a wonderful library. It’s made even more wonderful by the vast number of extensions, one of which is is the CSS Image Preloader, written by the JavaScript masters at the Filament Group.

What’s cool about this approach is that it’s a great balance between the other two: It’s simple, only requiring two javascript files (jquery core and the plugin) and a couple lines of code, but unlike the manual method of typing filenames, this plugin automatically parses linked and imported stylesheets. So if you change image urls, or add or remove images from a page, the plugin does the tough work for you. No need to update anything else. They have a great demo set up over at their website as well.

$(document).ready(function(){
  $.preloadCssImages();
});

Ultimately, the ‘right’ approach depends on what your individual needs are. I can see applications and arguments for and against all three of these examples. The first is pure CSS, which is always a plus in my book, but it also requires that you decide on a good way to organize your related images into sprites. The latter two both require JavaScript, which is almost always fine these days, but some people prefer to browse with it turned off, and it’s up to us developers to make sure that their experience isn’t hindered (much) because they chose to not trust our scripts.

Comments

blog comments powered by Disqus