Thursday, November 15, 2007

Faster Page Loads With Image Aggregation

I'm so rarely impressed, that when the stars align with the correct ingredients - newness, cleverness, utility (and stardust) - I'll be recharged with enough school-girl giddiness for a good week. Today I realized the beauty of faster page loads with image aggregation. Naturally I had to run home and try this trick on SnipSnipe, it's now 2am and I'm still not sick of it! It works like this:

Take all of the standard images on your website and turn them into div/span elements of matching width/height. In SnipSnipe, I replaced the upper-right Firefox image:

<img src="/images/firefox.gif" />
With:
<div id="ffimg" />
Using CSS, we can create an object of similar height and width, setting the background image as the image we wish to see:
#ffimg {
width:211px;
height:92px;
background-image: url('/images/firefox.gif');
background-repeat: no-repeat;
background-position: 0px 0px;
}
This is such an old trick you can find it painted on cave walls. A user will see the image in their browser as though it were inline via the img tag. Sure, you gain flexibility, but the way this ball lays we don't exactly gain any strokes. If we do this with 15 images, the browser still must make 15 requests to the server - but we are one step closer.

Our next task is to create an image that contains all images we want loaded onto the page. The SnipSnipe version is right here.

Now for every image it is a simple matter of altering the css to point to the same big image, only reposition the image to the correct pixel location.
#ffimg {
width:211px;
height:92px;
background-image: url('/images/big.gif');
background-repeat: no-repeat;
background-position: -208px 0px;
}
This example shows a 211x92 pixel area of the big.gif image starting 208 pixels from the left side of the div (you must make them negative numbers since they shift left).

A quick tip: if you set the background of an 'a' tag to one image, it's a fast way to do a rollover - just shift the background-position on a:hover.

And that's it! The example I used contains 12 separate images aggregated into one. So rather than a dozen requests totaling 21k of data transfered, instead there is only one request of similar data size. As we like to say in the biz, it's chunky not chatty - reduces strain on your server and serves up images faster than piecemeal.

0 comments: