PictureFill – A responsive images technique

Responsive Images

If your web application takes more than 3 seconds to load, you will soon get a call from the the latency police to explain yourself. Users expect snappy applications otherwise they will move on to the next website with better user experience. For businesses, you can not overstate the importance of fast applications as this could be the difference between success and failure. One of the reasons most web pages take a long time to load is the amount of requests made by the browser and the size of the files that need to be pre-loaded. Reducing the amount of requests, is at the core of improving user experience.

Recently in my day job, I was assigned a task of creating a prototype to demonstrate responsive images. Fishing rod in hand I headed off fishing for some new techniques. There is no shortage of server and client side techniques but I settled for PictureFill.

What is PictureFill?

PictureFill is a responsive image technique devised by Scott Jehl that makes use of the proposed picture element and media queries to serve images based on browser window size.

How does it work?

An img element is created on the fly using JavaScript based on the source and media query specified within the picture element. This prevents unnecessary overheads that are otherwise incurred by pre-loading large files, especially on small or low speed devices.

Implementation – Some code please!

Head off to the Github code repository and download the code files. The code is very well documented and includes examples. I will nonetheless give a quick run down on the html markup.

PictureFill HTML markup

<picture data-picture data-alt="big pebbles">
  <source data-src="img/pebbles_small.jpg">
  <source data-src="img/pebbles_medium.jpg" data-media="(min-width: 400px)">
  <source data-src="img/pebbles_large.jpg" data-media="(min-width: 800px)">
  <source data-src="img/pebbles_extralarge.jpg" data-media="(min-width: 1000px)">

  <!-- Fallback if no JS -->
    <noscript>
      <img src="img/small.jpg" alt="big pebbles">
    </noscript>
</picture>

In the snippet above, I use the picture element to nest all the various image sources using, well the source element. Note that I also specify the screen resolutions using media queries passed as values for the data-media attribute. The beauty here is the ability to cater for as many screen resolutions as you want.

For users with JavaScript disabled, we have a fallback image which is wrapped in noscript tags. This piece of code will not be executed by browsers running JavaScript.

Well as usually, IE demands special treatment. Using IE conditional comments we can provide a one-size-for-all image for IE8 and below as Media Queries are not supported here. For example if I wanted to serve the medium image to IE8 and below, I can nest the following inside the picture element:
<!–[if (lt IE 9) & (!IEMobile)]>
  <source data-src=”img/thumbs/pebbles_medium_thumb.jpg”></div>
<![endif]–>

If you are understandably apprehensive about using the picture element as it’s still in draft status with the w3c, you can replace the picture and source tags with the div element. Remember however to make the switch in the JavaScript as well i.e replace all the picture instances with div. My take on standards is that; they do not really mean that much if the browsers do not implement the module in question. After all users are not concerned about whether the your code is legal or not. That’s not to say that we should totally disregard semantics and standards. Word is that a few browsers have began implementing the picture/source model.

Summary

To many this might seem a very involved workaround to a problem that does not yet have a standardized solution, but until a fix comes along, this is a semantic workaround for the purist. As I mentioned earlier, there is no shortage of polyfills and workarounds in the web dev community, but this by far gets my vote.

Useful resources

  • Adaptive Images – a server side responsive images technique
  • HiSRC – a jQuery plugin for responsive images
  • Senchia.IO – cloud based service for mobile development.

2 thoughts on “PictureFill – A responsive images technique

  1. Hi Samson,

    Interesting article, thanks. First up, I haven’t used any responsive images technique, but will offer an opinion anyway :o)

    I’d be in favour of a technique that doesn’t require a javascript file to download and execute to determine the sizes to use. Otherwise you could get a ‘flash of unstyled content’ – the rest of the page will load then wait for the images.

    Adaptive Images sounds better to me – a single line of JS in the sets a cookie which sends the screen res with all subsequent image requests so the server can determine which variant of each image to send back. Of course you need control over the server side to implement this which isn’t always the case :o)

    Maybe some metric could be included as well to estimate the latency of the connection so the server knows whether to send low- or high- fidelity images, to suit the user’s connection speed. The HTML5 navigation timing API could be used:

    document.cookie = ‘dimensions=w:’ + window.screen.availWidth + ‘,h:’ + window.screen.availHeight + (window.performance ? ‘,responseTime:’ + (window.performance.timing.responseStart – window.performance.timing.navigationStart) : ”) + ‘;domain=images.localhost’;

    It’s not an exact science but maybe worth a look. Small screen res used to equal slow bandwidth and vice versa but no longer of course.

    cheers, keep the articles coming!
    Jon

  2. Hi Jon, thanks for the feedback. I totally agree with your sentiment with regards to the over dependence on JS to serve images or style pages for that matter.

    Ideally we should be using server side technologies to server content and I agree Adaptive Images trumps any other client side based techniques. However, and you can probably attest to this, our hands are often tied, so to speak, when it comes to what server language is used in a given organisation. So, adaptive images which is PHP based, might be off the table. In such cases you would have no choice but to look at client side techniques.

    I believe that client side based techniques are of little consequence on small applications especially if we write modular JavaScript and tap into Asynchronous Module Definition (AMD). We should also not forget that browsers are getting faster by the minute.

    btw, the HTML5 navigation timing API looks sweet.

Leave a Reply

Your email address will not be published. Required fields are marked *