Be careful using images in CSS and on pages

Let me start by telling a short story. A few weeks ago I was approached by a small business owner who wanted me to take over as webmaster for her site. Partly she wanted some small changes, partly she felt the site was loading far too slowly.

I looked the site over and on the surface it look quite impressive. It was a WordPress site with a very elegant commercial business theme. But it did indeed load very slowly - the small front page used 7.6 seconds to load according to Pingdom Tools.

It wasn't hard to see why: The page loaded almost 70 elements. That is - it made 68 HTTP calls. A lot of them were to tiny images: several 1x1pixel images of different colors used to produce horizontal lines, several 1x2 pixel images, some lines, bullets in 4 different colors, four small arrows - two directions and two colors, and so on. Some were used as images in the HTML, some were used as backgrounds in CSS styles.

Making fewer HTTP requests is, as we all know, the most important factor of all in making a web site load faster. This site loaded all sorts of images - virtually everything that wasn't text was built from image slices. Borders, rounded corners, backgrounds - all were images, bound together by intricate and elaborate HTML and CSS that somehow tied it all together. It looked pretty, but code-wise it was a mess.

So I went to work:

  • First I converted the six WordPress pages into pure HTML pages. That got rid of quite a bit of overhead that was unnecessary for a static site, and reduced the load time by about a second.
  • Then I got rid of as many of the small images that could be replaced by CSS as possible: turned them into solid one or two pixel borders, used the CSS3 for rounded corners, replaced bullets and arrows that were images with symbols and characters from the extended character set, and so on.
  • Next were slightly larger images that couldn't easily be replaced - many of them I made as small and light as possible, and turned them into base64 data URLs and used them as backgrounds instead of the original images. Each image replaced by an inlined image is one HTTP call less (I will write more about this later, sufficient to say for now is that among the only browsers not supporting this and requiring special handing is IE 7).
  • When this was done I was down to about 25 HTTP requests. A CSS sprite later I was down to 16.
  • Then, finally, I merged the two external CSS files to one (much fewer rules too now), and merged the 4 external Javascripts into one and minified both CSS and Java.

Now I was down to 12 HTTP requests and had efficient CSS and HTML. As a final step I web-optimized all the remaining images. I could perhaps have done even more, but now the gains started to look like they wouldn't be proportional to the time costs, so I stopped. Now the page loaded in 1.2 seconds, looked equally good, and had better SEO as well. I was satisifed. The client was very pleased.

The lesson

The point of this story is not that one shouldn't use images: I strongly believe that images are tremendously important if you want a site to look interesting. My point is rather that one should use them with extreme caution and only when CSS can't do it, sprites are impractical and inlining isn't an option (for instance because the image is too large). The gains in terms of speed when images are used smartly can be pretty big - in the case I just described they were over 80 percent (actually 84.2%).

Conservative use of images and efficient use of CSS, including sprites and in-lining, works well and can give huge performance gains.

Posted: September 2011

Previous post || Next post

Flower, beauty
CSS

Consider supporting

Blogging and web design is my living. Even though I give away for free, it has taken me time to develop, test and write up.

If you find the site useful, a donation would be very much appreciated.

Thank you for your support to further develop this site!