Menu Search
Jump to the content X X
Smashing Conf Barcelona

You know, we use ad-blockers as well. We gotta keep those servers running though. Did you know that we publish useful books and run friendly conferences — crafted for pros like yourself? E.g. our upcoming SmashingConf Barcelona, dedicated to smart front-end techniques and design patterns.

Automate Your Responsive Images With Mobify.js

Responsive images are one of the biggest sources of frustration in the Web development community. With good reason, too: The average size of pages has grown from 1 MB to a staggering 1.5 MB1 in the last year alone. Images account for more than 60% of that growth, and this percentage will only go up2.

Automate Your Responsive Images With Mobify.js

Much of that page weight could be reduced if images were conditionally optimized based on device width, pixel density and modern image formats (such as WebP3). These reductions would result in faster loading times and in users who are more engaged and who would stick around longer. But the debate isn’t about whether to optimize images for different devices, but about how to go about doing so.

Further Reading on SmashingMag:

In an ideal world, we would continue using the img tag, and the browser would download exactly what it needs based on the width of the device and the layout of the page. However, no functionality like that currently exists. One way to get functionality similar to that would be to change the src attribute of img elements on the fly with JavaScript, but the lookahead pre-parser (or preloader) prevents this8 from being a viable option.

The first step to overcoming this problem is to create a markup-based solution that allows for alternate image sources to be delivered based on a device’s capabilities. This was solved with the introduction of the picture element9, created by the W3C Responsive Images Community Group (although no browser currently implements it natively).

However, the picture element introduces a whole new problem: Developers must now generate a separate asset for every image at every breakpoint. What developers really need is a solution that automatically generates small images for small devices from a single high-resolution image. Ideally, this automated solution would make only one request per image and would be 100% semantic and backwards-compatible. The Image API in Mobify.js2010 provides that solution.

The <picture> Element As The Upcoming Best Practice Link

The picture element is currently the frontrunner to replace the img element11 because it enables developers to specify different images for different screen resolutions in order to solve the problem of both performance and art direction12 (although the new srcN proposal13 is worth looking into). The typical set-up involves defining breakpoints14, generating images for each breakpoint and then writing the picture markup for the image. Let’s see how we can make the following image responsive using a workflow that includes the picture element:

President Obama and Governor Christi15

We’ll use a baseline of 320, 512, 1024 and 204816 pixels.

First, we need to generate a copy of each image for those different resolutions, either by using a command-line interface (CLI) tool such as Image Optim17 or by saving them with Photoshop’s “Save for web” feature. Then, we would use the following markup:

    <source src="responsive-obama-320.png">
    <source src="responsive-obama-512.png" media="(min-width: 512px)">
    <source src="responsive-obama-1024.png" media="(min-width: 1024px)">
    <source src="responsive-obama-2048.png" media="(min-width: 2048px)">
    <noscript><img src="responsive-obama-320.png"></noscript>

One problem with this markup is that, in its current configuration, our image would not be optimized for mobile devices. Here is the same image scaled down to 320 pixels wide:

President Obama and Governor Christi18

Identifying the people in this photo is difficult. To better cater to the smaller screen size, we need to use the power of art direction to crop this photo for small screens:


Because this file isn’t simply a scaled-down version of the original, the name of the file should be given a different structure (so, responsive-obama-mobile.png, instead of responsive-obama-320.png):

    <source src="responsive-obama-mobile.png">
    <source src="responsive-obama-512.png" media="(min-width: 512px)">
    <source src="responsive-obama-1024.png" media="(min-width: 1024px)">
    <source src="responsive-obama-2048.png" media="(min-width: 2048px)">
    <noscript><img src="responsive-obama-512.png"></noscript>

But what if we want to account for high-DPI (dots per inch) devices? The picture element’s specification has a srcset attribute that allows us to easily specify different images for different pixel ratios. Below is what our markup would look like if we used the picture element.

    <source srcset="responsive-obama-mobile.png 1x, responsive-obama-mobile-2x.png 2x">
    <source srcset="responsive-obama-512.png 1x, responsive-obama-1024.png 2x" media="(min-width: 512px)">
    <source srcset="responsive-obama-1024.png 1x, responsive-obama-1024.png 2x" media="(min-width: 1024px)">
    <source srcset="responsive-obama-2048.png 1x, responsive-obama-4096.png 2x" media="(min-width: 2048px)">
    <noscript><img src="responsive-obama-512.png"></noscript>

Here we have introduced a couple of new files (responsive-obama-mobile-2x.png and responsive-obama-4096.png) that must also be generated. At this point, we’ll have six different copies of the same image.

Let’s take this a step further. What if we want to conditionally load our images in a more modern format, such as WebP, according to whether the browser supports it? Suddenly, the total number of files we must generate increases from 6 to 12. Let’s be honest: No one wants to generate multiple versions of every image for various resolutions and have to constantly update those versions in the markup. We need automation!

The Ideal Responsive Image Workflow Link

The ideal workflow is one that allows developers to upload images in the highest resolution possible while still using the img element in such a way that it automatically resizes and compresses the images for different browsers. The img element is great because it is a simple tag for solving a simple problem: displaying images for users on the Web. Continuing to use this element in a way that is performant and backwards-compatible would be ideal. Then, when the need for art direction arises and scaling down images is not enough, we could use the picture element; the branching logic built into its syntax is perfect for that use case.

This ideal workflow is possible using the responsive Image API in Mobify.js2010. Mobify.js is an open-source library that improves responsive websites by providing responsive images, JavaScript and CSS optimization, adaptive templating and more. The Image API automatically resizes and compresses img and picture elements and, if needed, does it without changing a single line of markup in the back end. Simply upload your high-resolution assets and let the API take care of the rest.

Automatically Make Images Responsive Without Changing The Back End Link

The problem of responsive images is a hard one to solve because of the lookahead pre-parser, which prevents us from changing the src attribute of an img element on the fly with JavaScript in a performant way. The pre-parser is a feature of browsers that starts downloading resources as fast as possible by spawning a separate thread outside of the main rendering thread and whose only job is to locate resources and download them in parallel. The way the pre-parser works made a lot of sense prior to responsive design, but in our multi-device world, images in the markup are not necessarily the images we want users to download; thus, we need to start thinking of APIs that allow developers to control resource loading without sacrificing the benefits of the pre-parser. For more details on this subject, consider reading Steve Souders’ “I <3 Image Bytes21.”

One way that many developers avoid the pre-parser is by manually changing the src attribute of each img into data-src, which tricks the pre-parser into not noticing those images, and then changing data-src back to src with JavaScript. With the Capturing API22 in Mobify.js, we can avoid this approach entirely, allowing us to be performant while remaining completely semantic23 (no <noscript> or data-src hacks needed). The Capturing technique stops the pre-parser from initially downloading the resources in the page, but it doesn’t prevent parallel downloads. Using Mobify.js’ Image API in conjunction with Capturing, we are able to have automatic responsive images with a single JavaScript tag.

Here is what the API call looks like:

    var capturedDoc = capture.capturedDoc;
    var images = capturedDoc.querySelectorAll('img, picture');
    Mobify.ResizeImages.resize(images, capturedDoc) 

This takes any image on the page and rewrites the src to the following schema:<format><quality>/<maximum width>/<maximum height>/<url>

For example, if this API was running on the latest version of Chrome for Android, with a screen 320 CSS pixels wide and a device pixel ratio of 2, then the following image…

<img src=''>

… would be rewritten to this:

<img src='//'>

The image of the forest would be resized to 640 pixels wide, and, because Chrome supports WebP, we would take advantage of that in order to reduce the size of the image even further. After the first request, the image would be cached on Mobify’s CDN for the next time it is needed in that particular size and format. Because this image of the forest does not require any art direction, we can continue using the img element.

You can see an example of automatic image resizing24 for yourself. Feel free to open your Web inspector to confirm that the original images do not download!

Using this solution, we simplify our workflow. We only upload a high-resolution asset for each image, and then sit back and let the the API take care of resizing them automatically. No proxy in the middle, no changing of any attributes — just a single JavaScript snippet that is copied to the website. Go ahead and try it out by copying and pasting the following line of code at the top of your head element. (Please note that it must go before any other tag that loads an external resource.)

<script>!function(a,b,c,d,e){function g(a,c,d,e){var f=b.getElementsByTagName("script")[0];a.src=e,,a.setAttribute("class",d),f.parentNode.insertBefore(a,f)}a.Mobify={points:[+new Date]};var f=/((; )|#|&|^)mobify=(d)/.exec(location.hash+"; "+b.cookie);if(f&&f[3]){if(!+f[3])return}else if(!c())return;b.write('<plaintext style="display:none">'),setTimeout(function(){var c=a.Mobify=a.Mobify||{};c.capturing=!0;var f=b.createElement("script"),h="mobify",i=function(){var c=new Date;c.setTime(c.getTime()+3e5),b.cookie="mobify=0; expires="+c.toGMTString()+"; path=/",a.location=a.location.href};f.onload=function(){if(e)if("string"==typeof e){var c=b.createElement("script");c.onerror=i,g(c,"main-executable",h,mainUrl)}else a.Mobify.mainExecutable=e.toString(),e()},f.onerror=i,g(f,"mobify-js",h,d)})}(window,document,function(){var a=/webkit|msies10|(firefox)[/s](d+)|(opera)[sS]*version[/s](d+)|3ds/i.exec(navigator.userAgent);return a?a[1]&&+a[2]<4?!1:a[3]&&+a[4]<11?!1:!0:!1},

// path to mobify.js

// calls to APIs go here
function() {
  var capturing = window.Mobify && window.Mobify.capturing || false;

  if (capturing) {
      var capturedDoc = capture.capturedDoc;

      var images = capturedDoc.querySelectorAll("img, picture");

      // Render source DOM to document

(Please note that this script does not have a single point of failure. If Mobify.js fails to load, then the script will opt out and your website will load as normal. If the image-resizing servers are down or if you are in a development environment and the images are not publicly accessible, then the original images will load.)

You can also make use of the full documentation25. Browser support for the snippet above is as follows: All Webkit/Blink based browsers, Firefox 4+, Opera 11+, and Internet Explorer 10+.

Resizing img elements automatically is great for the majority of use cases. But, as demonstrated in the Obama example, art direction is necessary for certain types of images. How can we continue using the picture element for art direction without having to maintain six versions of the same image? The Image API will also resize picture elements, meaning that you can use the picture element for its greatest strength (art direction) and leave the resizing up to the API.

Resizing <picture> Elements Link

While automating the sizes of images for different browsers is possible, automating art direction is impossible. The picture element is the best possible solution for specifying different images at different breakpoints, due to the robust branching logic built into its defined syntax (although as mentioned before, srcN is a more recent proposal that offers very similar features). But, as mentioned, writing the markup for the picture element and creating six assets for each image gets very complicated:

    <source srcset="responsive-obama-mobile.png 1x, responsive-obama-mobile-2x.png 2x">
    <source srcset="responsive-obama-512.png 1x, responsive-obama-1024.png 2x" media="(min-width: 512px)">
    <source srcset="responsive-obama-1024.png 1x, responsive-obama-1024.png 2x" media="(min-width: 1024px)">
    <source srcset="responsive-obama-2048.png 1x, responsive-obama-4096.png 2x" media="(min-width: 2048px)">
    <noscript><img src="responsive-obama-512.png"></noscript>

When using the Image API in conjunction with the picture element, we can simplify the markup significantly:

    <source src="responsive-obama-mobile.png">
    <source src="responsive-obama.png" media="(min-width: 512px)">
    <img src="responsive-obama.png">

The source elements here will be automatically rewritten in the same way that the img elements were in the previous example. Also, note that the markup above does not require noscript to be used for the fallback image to prevent a second request, because Capturing allows you to keep the markup semantic.

Mobify.js also allows for a modified picture element, which is useful for explicitly defining how wide images should be at different breakpoints, instead of having to rely on the width of devices. For example, if you have an image that is half the width of a tablet’s window, then specifying the width of the image according to the maximum width of the browser would generate an image that is larger than necessary:

In this case, automatically specifying a width according to the browser’s width would create an unnecessarily large image.

To solve this problem, the Image API allows for alternate picture markup that enables us to override the width of each source element, instead of specifying a different src attribute for each breakpoint. For example, we could write an element like this:

<picture data-src="responsive-obama.png">
    <source src="responsive-obama-mobile.png">
    <source media="(min-width: 512px)">
    <source media="(min-width: 1024px)" data-width="512">
    <source media="(min-width: 2048px)" data-width="1024">
    <img src="responsive-obama.png">

Notice the use of the data-src attribute on the picture element. This gives us a high-resolution original image as a starting point, which we can use to resize into assets for other breakpoints.

Let’s break down how this would actually work in the browser:

  • If the browser is between 0 and 511 pixels wide (i.e. a smartphone), then use responsive-obama-mobile.png (for the purpose of art direction).
  • If the browser is between 512 and 1023 pixels wide, then use responsive-obama.png, because src is not specified in the source element corresponding to that media query. Automatically determine the width because data-width isn’t specified.
  • If the browser is between 1024 and 2047 pixels wide, then use responsive-obama.png, because src is not specified in the sourceelement corresponding to that media query. Resize to 512 pixels wide, as specified in the data-width attribute.
  • If the browser is 2048 pixels or wider, then use responsive-obama.png, because src is not specified in the source element corresponding to that media query. Resize to 1024 pixels wide, as specified in the data-width attribute.
  • If JavaScript isn’t supported, then fall back to the regular old img tag.

The Image API will run on each picture element, transforming the markup into this:

<picture data-src="">
    <source src="//">
    <source src="//" media="(min-width: 512px)">
    <source src="//" media="(min-width: 1024px)" data-width="512">
    <source src="//" media="(min-width: 2048px)" data-width="1024">
    <img src="responsive-obama.jpg">

The Picture polyfill (included in Mobify.js) would then run and select the appropriate image according to the media queries. It will also work well when browser vendors implement the picture element natively.

See a page that uses the modified picture element markup27 for yourself.

Using the Image API without Capturing Link

One caveat with Capturing is that it requires the script to be inserted in the head element, which is a blocking JavaScript call that can delay the initial downloading of resources. The total length of delay on first load is approximately 0.5 seconds on a device with a 3G connection28 (i.e. including the DNS lookup and downloading and Capturing), less on 4G or Wi-Fi, and about 60 milliseconds on subsequent requests (since the library will have been cached). But the minor penalty is a small price to pay in exchange for being easy to use, backwards-compatible and semantic.

To use the Image API without Capturing to avoid the blocking JavaScript request, you need to change the src attribute of all of your img elements to x-src (you might also want to add the appropriate noscript tags if you’re concerned about browsers on which JavaScript has been disabled) and paste the following asynchronous script right before the closing head tag:

<script src="//">
    var intervalId = setInterval(function(){
        if (window.Mobify) {
            var images = document.querySelectorAll('img[x-src], picture');
            if (images.length > 0) {
            // When the document has finished loading, stop checking for new images
            if (Mobify.Utils.domIsReady()) {
    }, 100);

This script will load Mobify.js asynchronously, and when finished loading, will start to loading the images as the document loads (it does not need to wait for the entire document to finish loading before kicking off image requests).

Using The Image API For Web Apps Link

If you are using a client-side JavaScript model-view-controller (MVC) framework, such as Backbone or AngularJS, you could still use Mobify.js’ Image API. First, include the Mobify.js library in your app:

<script src="//"></script>

Then, rewrite image URLs with the method outlined in Mobify.js’ documentation29:


This method accepts an absolute URL and returns the URL to the resized image. The easiest way to pass images into this method is by creating a template helper (for example, {{image_resize '/obama.png' }} in Handlebars.js) that executes the getImageUrl method in order to generate the image’s URL automatically.

Using Your Own Image-Resizing Back End Link

Images are resized through Mobify’s Performance Suite30 resizing servers, which provides support for automatic resizing, WebP, CDN caching and more. There is a default limit on how many images you can convert for free per month, but if you’re driving a large volume of traffic, then give Mobify a shout and we’ll find a way to help. The API also allows you to use a different image-resizing service31, such as Src, or your own backend service.

How Can Browser Vendors Better Support Responsive Images? Link

The Webkit team has recently implemented the src-set attribute, and so will Blink and Gecko in the coming months. This is a huge step in the right direction, as it means that browser vendors are taking the responsive image problem seriously. However, it doesn’t solve the art direction problem, nor does it prevent the issue of needing to generate multiple assets at different resolutions.

The developer community recently got together to discuss32 the responsive image problem. One of the more interesting proposals discussed was Client Hints33 from Ilya Grigorik, which is a proposal that involves sending device properties such as DPR, width and height in the headers of each request. I like this solution, because it allows us to continue using the img tag as per usual, and only requires us to use the picture (or srcN) when we need branching logic to do art direction. Although valid concerns have been raised about adding additional HTTP headers and using content negotiation34 to solve this problem. More importantly, for established websites with thousands of images, it may not be so easy to route those images through a server that can resize using the headers provided by Client Hints. This could be solved by re-writing images at the web server level, or with a proxy, but both of those can be problematic to setup. In my opinion, this is something we should be able to handle on the client through greater control over resource loading.

If developers had greater control over resource loading, then responsive images would be a much simpler problem to tackle35. The reason why so many responsive image solutions out there are proxy-based is because the images must be rewritten before the document arrives to the browser. This is to accommodate the pre-parser’s attempt to download images as quickly as possible. But proxies can be very problematic in their security and scalability and, really, if we had an easy way to interact with the pre-parser, then many proxy-based solutions would redundant.

How can we get greater control over resource loading while still getting all of the benefits from the pre-parser? The key thing here is that we do not want to simply turn off the pre-parser — its ability to download assets in parallel is a huge win and one of the biggest performance improvements introduced into browsers. (Please note that the Capturing API does not prevent parallel downloads.) One idea is to provide a beforeload event that fires before each resource on a page has loaded. This event is actually available when one uses Safari browser extensions36, and in some browsers it is available in a very limited capacity. If we could use this event to control resource loading in a way that works with the pre-parsing thread, then Capturing would no longer be needed. Here is a basic example of how you might use the beforeload event, if it worked as described:

function rewriteImgs(event) {
    if ( === "IMG") {
        var img =;
        img.src = "//" + screen.width + "/" + img.src;
document.addEventListener("beforeload", rewriteImgs, true);

The key challenge is to somehow get the pre-parser to play nice with JavaScript that is executed in the main rendering loop. There is currently a new system being developed in browsers called the Service Worker37, which is intended to allow developers to intercept network requests in order to help build web applications that work offline. However, the current implementation does not allow for intercepting requests on the initial load. This is because loading an external script which controls resource loading would have to block the loading of other resources — but I believe it could be modified38 to do so in a way that does not sacrifice performance through the use of inline scripts.

Conclusion Link

While there are many solutions to the problem of responsive images, the one that automates as much work as possible while still allowing for art direction will be the solution that drives the future of Web development. Consider using Mobify.js to automate responsive images today if you are after a solution that does the following:

  • requires you to generate only one high-resolution image for each asset, letting the API take care of serving smaller images based on device conditions (width, WebP support, etc.);
  • makes only one request per image;
  • allows for 100% semantic and backwards-compatible markup that doesn’t require changes to your back end (if using Capturing);
  • has a simplified picture element that is automatically resized, so you can focus on using it only for art direction.

(Front page image credits: Creating High-Performance Mobile Websites39)

(al, ea, il)

Footnotes Link

  1. 1
  2. 2
  3. 3
  4. 4
  5. 5
  6. 6
  7. 7
  8. 8
  9. 9
  10. 10
  11. 11
  12. 12
  13. 13
  14. 14
  15. 15
  16. 16
  17. 17
  18. 18
  19. 19
  20. 20
  21. 21
  22. 22
  23. 23
  24. 24
  25. 25
  26. 26
  27. 27
  28. 28
  29. 29
  30. 30
  31. 31
  32. 32
  33. 33
  34. 34!msg/blink-dev/c38s7y6dH-Q/F4stpsFmih8J
  35. 35
  36. 36
  37. 37
  38. 38
  39. 39

↑ Back to top Tweet itShare on Facebook

Shawn is an Engineering Manager on the Product and Customer Success Teams at Mobify. He loves to hack both on the front-end and back-end, with a heavy focus on the user experience. When he isn't hacking, you likely find him playing hockey/video games, eating, or travelling. Shawn has a BSc in Computer Science from Simon Fraser University in Vancouver. You can follow him at @shawnjan8.

  1. 1

    Brilliant! I was pondering responsive images and how to optimize them for the last month and Mobify.js is an awesome solution.

  2. 2

    Frederick Andersen

    October 24, 2013 4:35 am

    What a wonderful article. I’ll be using Mobify.js from now on.

    Thanks, Shawn.

  3. 3

    Hi Shawn!
    Great post, and a very interesting technique. I’ll make sure to look further into it.

    One major thing that bothers me though is your use of the actual picture element is your examples.
    Since the picture proposal is still a draft, and highly subject to changes, adding it to the markup can actually be harmful to the standardization process and can create future compatibility issues.

    A different pattern (such as picturefill’s use of spans with a “data-picture” attribute) is highly preferred.

    Would it be possible to modify the examples accordingly?

  4. 6

    The state of the picture element’s acceptance notwithstanding, and realizing the code in this article is for demonstration purposes, I still think it’s worth mentioning that for bandwidth and accessibility purposes, descriptive text should be included at the bottom of the stack. Something along the lines of this:

    Reflecting the idea that the first media query is supporting a lack of media queries, the text description provides context for users who cannot load or are unable to visually parse an image element.

    • 7

      Shawn Jansepar

      October 24, 2013 7:36 am

      Hi Eric,

      Would it maybe make sense to make it an alt attribute on the picture element itself rather then a paragraph tag inside the element?

      • 8

        I believe, and correct me if I’m wrong here, that the picture element does not currently support the alt attribute. The W3C working draft ( has an example applied to only the img tag at the bottom of the stack, but it is a working draft so who knows what it’ll wind up finally being.

        Personally, I think they’re trying to mimic the pattern of the video and audio elements, where the fallback descriptive text is a child of the overall tag and presented after everything else. I’m willing to bet that an alt attribute would have a lot better support for most assistive tech, though.

        Great article, by the way!

        • 9

          Shawn Jansepar

          October 25, 2013 2:45 pm

          Hmmm. Hopefully the alt text can be worked into the draft – I feel like that would make the most sense!

          And thanks for the compliments – much appreciated :)

  5. 10
    • 11

      Shawn Jansepar

      October 24, 2013 8:01 am

      Hi Eric, and other solutions like it (such as require you to change src to data-src for all images, which can be an unrealistic expectation for sites that already have thousands of images. Using Capturing, Mobify.js lets you avoid that, allowing you to be completely semantic.

      If you don’t want to use Capturing, Mobify.js can also resize images by controlling resource loading using data-src, but it does it a bit more intelligently. Instead of loading Mobify.js at the end of body, kicking off image requests after all CSS/scripts have loaded and executed, there is a snippet in my article that demonstrates how you can asynchronously load Mobify.js and start loading images ASAP.

    • 12

      Hi Shawn

      Informative article. Unfortunately the image quality of your mobify solution seems really poor. The following link below is served from mobify as an 85% JPEG with subsampling, however its looks far worse!

      Example here:

      With regards to they double request every new image Ouch!… First a 301 (Moved Permanently) then a 200 (ok) when they have offloaded it to rackspace.

      There are definitely better solutions out there.

      • 13

        Hi Whan,

        JPEG quality is a tuneable parameter in the HTTP API, e.g. and in the JavaScript API if you want to dig into the underlying code a bit:

        85 was chosen as the quality default as it seemed to provide a reasonable compromise between image quality and file size, though of course final output quality will depend on the compression level of the input image, the scaling applied and the resolution and quality of the final display device.

        Recompressing a JPEG from a JPEG is obviously never ideal from an image quality standpoint, but does provide a practical, automatic way of producing lighter weight image assets for existing web content.

  6. 14

    Any difference between using the code above, and creating a free Mobify account that supposedly requires a unique script to be used? If I just want the mage resizing, I assume I don’t need to bother with an account?

    • 15

      Shawn Jansepar

      October 25, 2013 12:49 am

      Hi Jake,

      The snippet in the article is enough to get you going to enable responsive images in your site. We do monitor all sites accessing our service, and if a website has more then 100K page views per month (subject to change: see, we will require an account be created to setup payment.

      Although there are a number of benefits of creating an account that you might be interested in – our Performance Suite offers not only responsive images, but automatic JavaScript/CSS minification/CDNification as well. We’ll also soon be providing analytics to show how much of an improvement it is making to your site over time using real user monitoring.

    • 16

      If you don’t want to sign up to Mobify, you can use another CDN, like Sencha:

  7. 17

    Awesome article Shawn!

    Will definitely give this a go soon. Just a quick question though? What are the SEO ramifications using this technique?



    • 18

      Shawn Jansepar

      October 26, 2013 11:37 am

      Hi Ned,

      I’m not an engineer at Google so I couldn’t tell you for sure, but from what I’ve research there should be no SEO ramifications. All of your content in the page remains indexable.

  8. 19

    Am I the only one scared into just outsourcing your image hosting like this?

  9. 21

    David Philippe

    October 29, 2013 1:46 am

    Hi Shawn

    Thanks for this great post and the exciting prospect of a flexible solution for responsive images.

  10. 23

    I’d say it’s more to do with device connection speed/bandwidth than it is to do with width, height and pixel density.

    If a user is on a mobile device connected to a fast WiFi or 4G connection, then they should be able to have access to the full-size, high-quality images if they wish.

    Having said that, it’s a difficult problem to solve because there’s no accurate way to detect speed/bandwidth at the moment.

    • 24

      Shawn Jansepar

      October 30, 2013 12:34 pm

      Hi Dareth,

      I would say it’s arguable as to whether or not we want to display lower quality images depending on the bandwidth… If you are on a Retina iPad, you might never want your users to see a very low quality blurry image, as that might effect the users perception of the website quality.

      There are libraries that can provide this if you want it though! Checkout Foresight.js:

  11. 25

    According to Fiddler IE10 (and the latest FF) is anyhow making the requests to the original files.

    The above screenshot was made for one of the mobify examples.

    • 26

      Shawn Jansepar

      October 30, 2013 10:02 am

      Hi Jakub,

      Firefox and IE seem to work a bit differently when it comes to their preload scanner. It seems as though with Webkit, it doesn’t kick off the preload scanner until the first resource is processed, which by this time, the plaintext tag will have hidden all the resources, while in FF and IE, they look for resources right away, potentially catching the first few images in the document. In IE and FF, whatever original images that have been kicked off will be cancelled quite quickly (it depends on your connection speed).

      Here is a screenshot that shows the original images in the page being cancelled quickly (this screenshot was for IE, but it’s the same behaviour for FF):

  12. 27

    This is a really nice post and approach. If the predicted picture element is implemented, the needed HTML source for this automation doesn’t have to be changed.

    Because of the heavy HTML markup, seen in this and other approaches, a colleague and me invented a vanilla javascript plugin named “pictureserve”.

    If you are interested, take a look at

    Our approach is to write the needed HTML as normal – one img tag only – and let the plugin do the rest.

    Any forks and ideas appreciated :)

  13. 28

    I’m not sure I would trust the “plaintext” node to stop the pre-parser, especially as it’s “deprecated since HTML 2” (see Mozilla website, no link due to spam detection).

    This is probably why your having problems with FF and IE still making those connections to download the original images (and I suspect in time Webkit/Blink will also have issues).

    Otherwise, thanks for experimenting and writing this up, it does summarise pretty much all of the problems, and hopeful solutions for the future.

  14. 29

    Take a look at this solution
    It’s a server side, but works well.

  15. 30

    “No proxy in the middle, no changing of any attributes — just a single line of JavaScript that is copied to the website.”

    But the code snippet, while not huge, is not exactly “a single line of code”.

    I hate to be picky, because the article and the service are quite good, but as engineers, we do strive for accuracy.

  16. 32

    A really interesting post. Thanks


↑ Back to top