Web Platform Team Blog

Adobe

decor

Making the web awesome

Image Progress Event Progress

In early January 2012, the Web Platform team began investigating adding progress events to images. The goal was to enable developers to more accurately track the load progress of their image resources, using progress events similar to those available with XMLHttpRequest. The feature would enable both HTML and JavaScript markup.

<img id="image" src="sample.jpg"
    onloadstart="showProgressBar()"
    onprogress="updateProgressBar(event)"
    onloadend="hideProgressBar()" />
var imageElement = document.createElement("img");
imageElement.onloadstart = showProgressBar;
imageElement.onprogress = updateProgressBar;
imageElement.onloadend = hideProgressBar;

A common approach today is to download the data using the progress event enabled XMLHttpRequest. The resulting XMLHttpRequest response can then be base-64 encoded as a data URI, and supplied as the src attribute on an image. (As a side note: the File API will eventually allow you to encode the data as a blob URI, but the API is not yet fully supported)

var imageElement = document.createElement("img");
var request = new XMLHttpRequest();
request.onloadstart = showProgressBar;
request.onprogress = updateProgressBar;
request.onloadend = function(e) {
    var imageElement = document.createElement("img");
    var encodedSrc = base64encode(request.responseText);
    imageElement.setAttribute("src",
        "data:image/jpg;base64," + encodedSrc);
};
request.open("GET", src, true);
request.overrideMimeType('text/plain; charset=x-user-defined');
request.send(null);

There are a few pain points here:

  • You have to manage the download of each image
  • Encoding as data URIs takes time and adds long strings to your document
  • Other domains must explicitly allow progress events for their resources

Image progress events appeared as a straightforward way of addressing these problems. The browser would still manage image downloads, the same as always, but would additionally fire off progress events for any interested listeners. There would be no need to translate between the XHR response and the image src attribute. And perhaps we could even find a way to provide meaningful progress events to cross domain images, while still respecting the security considerations involved.

We floated the idea to the community, through the WebKit and WhatWG mailing lists, and as a potential work item for WebKit.

The responses we received were supportive, but also raised security concerns focused around progress events for cross domain images. When loading images from another domain, unless that domain opts in via CORS, you are not able to determine the file size or download progress with XMLHttpRequests. We had initially wanted to share slightly more information via image progress events, providing something helpful even in the non-CORS case. Perhaps we could share the percentage downloaded, or, barring that, at least that the download was progressing.

Through discussions with some very knowledgable folks in the WebKit & WhatWG community, we came to realize that even a little bit of progress information could be used to reveal the original file size. Realistically, we could only provide progress events for same origin images, and cross origin images with the appropriate CORS headers.

At this point, we took a step back to look again at the three major pain points we were hoping to solve.

Other domains must explicitly allow progress events for their resources

Image progress events would need to respect the same security concerns as XMLHttpRequests. We could not share any more information for non-CORS cross-origin images.

Encoding as data URIs takes time and adds long strings to your document

As mentioned previously, as the File API matures, it will provide a more straightforward way of passing XMLHttpRequest responses to image elements.

You have to manage the download of each image

It seemed to us like developers wanting to monitor resource loading would be willing to write the Javascript to actually load the resource. Even with image progress events, feedback focused on the Javascript method of attaching progress listeners.

What we have decided to do, at least for now, is to put image progress events on the back burner. While that may sound like one less project we’re working on, rest assured that we’re drawing from a very long list of ideas. We’re also keeping tabs on some interesting new developments in the web community. And finally, don’t forget that we already have a bunch of really cool projects in the works.

3 Comments

  1. July 11, 2012 at 5:25 am, Ed said:

    Shame that you are putting this on hold because it appears to be a really good idea. However, security is key and if you are loading into another domain, surely there would always be some form of security barrier to prevent attacks. If you could get around that and make the flow easy to manage and understand, I think that it would be a great tool!

  2. July 25, 2012 at 12:22 am, Hana Giat said:

    Thanks for this information. This is indeed a clear description of the current status and the way to solve it.
    Having that said, I cannot agree with the decision to put this “on the back burner”. Performance measurement of websites is done in many cases by tools that are not developed with the web page itself, and in many cases added later or even dynamically (by output filters, for example). These tools have to hook into the page, but in order to keep the page maintainable must leave the smallest footprints on the page text. So the assumption that “developers wanting to monitor resource loading would be willing to write the Javascript to actually load the resource” seems to me incorrect.
    I believe that a progress on this issue is essential for web monitoring tools.

    • July 30, 2012 at 9:09 am, bear said:

      Hi Hana,

      Thanks for the feedback. What kind of statistics are you looking to track that can’t be monitored today?

      -Bear