Image-y nation

There’s a great article by Wilto in the latest edition of A List Apart. It’s called Responsive Images: How they Almost Worked and What We Need.

What all I really like about the article is that it details the the thought process that went into trying working out responsive images for the Boston Globe. Don’t get me wrong: I like it when articles provide code, but I really like it when they provide an insight into how the code was created.

The Filament Group team working on the Boston Globe site were attempting to abide by the two rules of responsive images that I’ve outlined before:

  1. The small image should be default.
  2. Don’t load images twice (in other words, don’t load the small images and the larger images).

There are three reasons for this: performance, performance, performance. As Luke put it so succinctly:

Being a Web designer & not considering speed/performance is like being a print designer & not considering how your colors will print.

That said, I came across a situation recently where loading both images for desktop browsers could actually be a pretty good thing to do.

Wait, wait! Here me out…

Okay, so the way that many of the responsive image techniques work is by means of a cookie. The basic challenge of responsive images is for the client to communicate with the server (and let it know the viewport size) before the server starts sending images. Because cookies can be used both by the client and the server, they offer a way to do that:

  1. As the document begins to load, set a cookie on the client side with JavaScript recording the viewport width.
  2. On the server side, when an image is requested, check for the contents of that cookie and serve up the appropriate image for the viewport size.

There are some variations on this: you could initially route all image requests to send back a 1x1 pixel blank .gif and then, after the page has loaded, use JavaScript to load in the appropriate image for the viewport size.

That’s the theory anyway. As Mat outlined in his article, there’s a bit of a race condition with the cookie being set by the client and the images being sent from the server. New browsers are doing some clever pre-fetching of images. That means they fetch the small images first, violating the second rule of responsive images.

But, like I said, in some situations that might not be so bad…

Josh is working on a responsive project at Clearleft right now—and doing a superb job of it—where he’s deliberately cutting the server-side aspect of responsive images out of the picture. He’s still starting with the small (mobile) images by default and then, after the page has loaded, swaps them out with JavaScript if the viewport is wide enough.

Suppose the small image is 20K and the large image is 60K. That means that desktop browsers are now loading 80K of images (instead of 60). On the face of it, this sounds like really bad news for performance… but because that extra 60K is being downloaded after the page has downloaded, the perceived performance isn’t bad at all. In fact, the experience feels quite snappy. Here’s what happens:

The markup contains the small image as well as some kind of indication where the larger size resides (either in a query string or in a data- attribute):

<img class="photo" src="basestar.jpg" alt="a spiky seed" data-fullsrc="basestar-large.jpg">

Spiky

That’s about 240 by 180 pixels. Now for the large-screen layout, we want those pictures to be more like 500 by 375 pixels:

@media screen and (min-width: 50em) {
    .photo {
        width: 500px;
        height: 375px;
    }
}

That results in a “blown up” pixely image.

Spiky

Once the page has loaded, that small image is swapped out for the larger image specified in the data- attribute.

Spiky

Large-screen browsers have now downloaded 20K more than they actually needed but the perceived performance of the page was actually pretty snappy:

  1. Blown-up pixely images act as placeholders while the page is downloading.
  2. Once the page has loaded, the full-sized images snap into place.

Does that sound familiar? This is exactly what the lowsrc attribute did.

I’m probably showing my age by even acknowledging the existence of lowsrc. It was a proprietary attribute created by Netscape back in the days of universally scarce bandwidth:

<IMG SRC=basestar.jpg LOWSRC=low-basestar.jpg ALT="a spiky seed">

(See how I’m using unquoted attributes and uppercase tags and attributes for added nostalgic value?)

The lowsrc value would usually be a monochrome version of the image in the src attribute.

a spiky seed in black and white

And we only had 256 colours to play with. You tell that to the web developers today …they wouldn’t believe you.

Seriously though, it’s funny how problems from the early days of the web have a habit of resurfacing. I remember when Ajax was getting popular, all the problems associated with frames rose from the grave: bookmarking, breaking the back button, etc. Now that we’re in a time of small-screen devices on low-bandwidth networks, we’re rediscovering a lot of the same issues we had when we were developing for 640 pixel wide screens with 28K or 56K modems.

Ultimately, I think that what the great brainstorming around fixing the problems with the img element shows is a fundamental impedance mismatch between the fluid nature of the web and the fixed pixel-based nature of bitmap images. We’ve got ems for setting type and percentages for specifying the proportions of our grids, but when it comes to photographic images, all we’ve got is the pixel—a unit that makes less and less sense every day.

Have you published a response to this? :