Image loading with image.decode()

The actual support to load an (large) image and add it into the DOM via JavaScript has some negative effects. The decoding of the image can block the main thread and by that cause jank in an app. To improve this behavior the browser developers came up with a new API specification for predecoding images.

The API provide an explicit decode function for an image with a success/failure callback when the image is loaded and decoded. After decoding the image authors could append it to the DOM, without causing a decoding delay.

Current practice loading an image into an app

When loading an image with JavaScript in the way we actually do, the image.onload handler guarantees that trying to use the image is going to work. At this time the image is not decoded. With the first time using the image data we usually get a delay to decoding overhead. So after inserting an image into the DOM a paint event occurs and this causes a synchronous decode of the image in the main thread. As a result the main thread is blocked.

The performance tool shows the delay synchronous image decoding causes. The browser main thread is blocked for more than 800 ms in this example. Of course this example uses a very big image to illustrate the effect. But if you think about a result list with many (normal sized) images and carousels the effect could cause jank also.

Screenshot DevTools decoding bigImage.jpg

Even when using the Promise API to load the image asynchronously we are still faced with the same effect. We only shift the insertion of the image into the DOM to a callback. So appending the image to the DOM still causes a synchronous decode of the image.

Using image.decode() function to load images

The usage of the decode function is very simple and supports us with the success/failure callback functionality we know from the Promise API.

In the example the author requests to decode an image element. The decode implies a load, followed by the decode of the image. The call returns a promise, which, when fulfilled, ensures that the image can be appended to the DOM without causing a decoding delay on the next frame.

Actual implementation status for API:

  • Chrome has ‘Intend to ship’
  • Safari has ‘Public support’
  • Firefox and Edge have ‘No public signal’

Useful Links: