Blink decodes off the main thread for image elements and for CSS styles (an image as an element's background style, for example). Moving the decode to the compositor thread (or the compositor worker thread pool?) does free-up the main thread to work on other tasks. We call this deferred decoding. With deferred decoding, the decode work remains on the critical path for presenting a frame to the display, so it can still cause animation jank.
The HTMLImageElement.decode()
API should help with the jank problem. Also deferred decoding does not work with SVG
image resources. There are still cases where decoding images happens synchronously on the main thread: 2D canvas drawImage()
and createPattern()
, and WebGL texture uploads.
For canvas-related usecases, there is a recently shipped API called createImageBitmap
that can be used for async decoding.
The API is async, but the implementation does not yet fully multi-thread all the work, this is still a work in progress.
Currently png and jpeg decoding are done in a background thread.
Chrome on Android has the same behavior as desktop Chrome.
A few things which could use an update here.