A true adaptive images solution

Adaptive images is the art of serving optimally sized images to different devices depending on screen resolution and bandwidth restraints. At the moment it’s one of the hardest problems to tackle within responsive webdesign. In fact there aren’t any good solutions currently.

Most of them focus on screen resolution, using either markup or media-queries, in their decision to load a low-res or high-res version of an image. An example of this is the newly proposed picture element by which you can define multiple images that are displayed depending on the available screen real estate:

<picture width="500" height="500">
   <source media="(min-width: 45em)" src="large.jpg">
   <source media="(min-width: 18em)" src="med.jpg">
   <source src="small.jpg">
   <img src="small.jpg" alt="">
   <p>Accessible text</p>
</picture>

This of course doesn’t solve much. The need for serving smaller sized images to a mobile user isn’t just about screen resolution… it’s also about network bandwidth. You could be on a retina iPad but on a 3G connection, so which of the images above should you get? According to the code, you’d get large.jpg… *D’OH*

Then there are some network bandwidth testing solutions, like Foresight.js, that determine which image resolution is most appropriate for your connection by first sending test-data to the browser and then measuring how long that takes. This to me seems flawed by design. The overhead of sending data to a browser, measuring it, discarding it, then downloading the right data, introduces a performance penalty that is likely worse then just sending over-sized images.

The right metric

In the end, the core of the problem is that we lack the right metric to base our logic on. Instead of trying to figure out for ourselves if a website visitor is on a fast or slow network connection, the browser should tell us. Your smartphone browser knows whether it’s on a 3G or on a Wifi network. And your desktop browser could also easily measure if you ISP is having a particularly slow day or that it’s rock-solid fast. The only thing we need from them is to pass on this information.

For example, by including a Network-Bandwidth request header:

GET / HTTP/1.1
Host: galaxy.fili.nl
Connection: keep-alive
Cache-Control: no-cache
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Pragma: no-cache
User-Agent: Mozilla/5.0 (X11; Linux i686) AppleWebKit/537.36 (KHTML, like Gecko) Ubuntu Chromium/28.0.1500.71 Chrome/28.0.1500.71 Safari/537.36
Accept-Encoding: gzip,deflate,sdch
Accept-Language: en-US,en;q=0.8,nl;q=0.6
Network-Bandwidth: 10Mbps

Or possibly by supporting bandwidth CSS media-queries:


@media (max-bandwidth: 10Mbps) {
    background-image: url(puppy-low-res.jpg);
}

@media (min-bandwidth: 10Mbps and max-bandwidth: 30Mbps) {
    background-image: url(puppy-medium-res.jpg);
}

@media (max-bandwidth: 30Mbps) {
    background-image: url(puppy-high-res.jpg);
}

This is the only true way to solve the adaptive images dilemma we face today. As a bonus, browsers could then also offer a switch to let users manually choose between a high-res or a low-res internet, maybe even on a per-site basis. Neato.

Sorry, but you’re wrong, information about bandwidth isn’t a solution. I could write about the details, but other people have done that already. For an extensive read: http://mobile.smashingmagazine.com/2013/01/09/bandwidth-media-queries-we-dont-need-em/

@Wout A nice read! Okay so it seems I’m a little late to the party :)

However I don’t fully agree with the conclusion of the Smashing article. It might be hard to implement in a browser but not impossible, and in my view still needed. Bandwidth testing seems to work well for video, maybe we need a new image format that contain multiple versions? Or simply make it a manual decision (a low/high-res browser switch) for the user? In the end, what are the alternatives? Just forgetting about slow networked users?

The official way forward in dealing with responsive images is going to be srcset, not a picture element. Webkit already has this implemented. See: http://mobile.smashingmagazine.com/2013/08/21/webkit-implements-srcset-and-why-its-a-good-thing/

Ah yes, I’ve read about it but didn’t realize Webkit already supports it. And according to that Smashing Article bandwidth profiling isn’t so far fetched: “envision a preference in your mobile browser allowing high-res images to only be requested while connected to WiFi, or a manual browser preference allowing you to only request low-resolution images when your connection is shaky.”

I agree that the actual standard used to determine a response is up for debate but the bottom line is HTTP headers need improvement. And the owness is on the browsers right now. We need to be able to trust headers and headers need to be supplying more information about their environment.

Another proposal to improve upon the headers that browser sent is client hints (http://css-tricks.com/client-hints/) which seems promosing, sadly it also doesn’t account for low network environments

Add a remark