Note, for readability I will change the names of the following JavaScript Objects to English text.
OffscreenCanvas
will be “offscreen canvas”.HTMLCanvasElement
will be “canvas”.ImageBitmap
will be “image bitmap”.
Introduction
Welcome to learning more about offscreen canvas; it’s a hidden gem of web technology! In this post, I go through several examples to show how to use offscreen canvas: like converting canvas data to blobs, image bitmaps, offscreen rendering, and transferring canvas context. I hope to show how useful this technology is and how it might apply in everyday development.
Offscreen canvas functions exactly the same as canvas, but it does not render to the web browser. Neither is the offscreen canvas tied to the DOM. This saves on processing power by not rendering to a screen, so complex renders like a 3D environment could be done more efficiently. Additionally, offscreen canvas is supported in separate JS browser environments like web and shared worker, in which they were really meant to be used.

Hello everyone, let’s paint together something magical.
Convert Canvas to Blob
The first example to show is making an image from an offscreen canvas.
|
|
Here, the script creates an offscreen canvas and its context; as well, note that I am using an offscreen canvas method called convertToBlob
. That method converts the hidden offscreen canvas image into binary format, or a blob. After making a blob, the script downloads the image using the good old anchor download trick.
As I was looking over MDN documentation learning about offscreen canvas, I noted that the method convertToBlob
is similar to canvas’ toBlob
method. There are differences between the two APIs other than the name; namely the method convertToBlob
returns a promise and toBlob
uses a callback method with the first parameter. Both methods accept image type and a quality parameters. As far as why one has a callback method while the other has a promise, I don’t quite know other than offscreen canvas is newer and perhaps implemented promises by default. I have read that callbacks are more for functional synchronous execution, while promises are more declarative asynchronous execution, which does make sense. Callbacks can get unwieldy really quick whereas promises may be utilized for more readable code in complex asynchronous scripts.
I think that a good use case for creating images with an offscreen canvas is making automated alterations to a lot of pictures at once. Processing a lot of pictures would take up the main JS execution and bog down the application. But if the images are sent to a shared or web worker, then automated processing can happen in the background. I do think that most modern day photo applications are based with a server backend to make alterations, but a more privacy focused alternative could easily use an offscreen canvas.
Using an Image Bitmap
An image bitmap is a high-performance, low-level representation of an image that can be used for processing in various contexts, like offscreen canvas. One purpose of image bitmaps is to provide an efficient transfer of image data between environments in JS. Additionally, image bitmaps can be compared to array buffers or streams, because they are all low level JS types. Pretty much all low-level types in JS are transferable, meaning the data can be swapped between contexts.
You can create an image bitmap from various sources, including HTMLImageElement
, canvas, Blob
, or even another image bitmap. In particular, the createImageBitmap()
method is used to generate an image bitmap asynchronously, which avoids blocking the main thread. When potentially alterating a lot of pictures in an automated fashion, transfering data via image bitmap is the way to go.
Here’s an example of creating an image bitmap and using it with an offscreen canvas. I mention image bitmaps in relation to offscreen canvas, because offscreen canvases and image bitmaps were meant to be used in web or shared workers. As well, image bitmaps and offscreen canvases may go hand in hand when processing images.
|
|
Rendering in Offscreen, Output to Bitmap
This next script I wrote got inspired from the MDN page for offscreen canvas with some slight modifications. The script queries for a canvas in the DOM and it creates a bitmap renderer context (which I didn’t know existed). Then the script creates an offscreen canvas with an animated drawing. Subsequent to the animation, that drawing gets sent as an image to the main canvas. In the following example, the animation I created was a ball rotating on a circle in 60 segments.
|
|
Similar to the batch image processing example I previously mentioned, let’s say if I loaded a high resolution photo in my web application, then I can process that high resolution photo in an offscreen canvas and immediately display the photo alterations in the browser. I can see this making for a responsive photo web application!
Canvas Transfer to Canvas Offscreen
This next test was probably the coolest thing to see. Declaring an offscreen canvas isn’t the only way to get one. You can also use the transferControlToOffscreen
from canvas.
|
|
The script queries the canvas element in DOM, and it transfers the canvas control into an offscreen canvas. Offscreen canvas is a “transferable” object, which means data can offload into a web worker. In JS, low level types are transferable between JS execution contexts. There in the web worker, the script can modify the original canvas across environments. This is because the rendering context is made in the web worker, while still being connected to the original canvas.
There were a few things that I discovered. If a context is made in the main execution, then the canvas can not be transferred to a web worker. As well if I used structuredClone
function then the original canvas couldn’t receive any updates from the web worker because there is no more connection to the original canvas.
Conclusion
I first came across an offscreen canvas just a few months ago, and it’s remained in my mind as a point to learn more about. So I spun up a workshop and the MDN documentation to learn more about the API. I’ve learned about using image bitmaps, data transferables, and web worker processing! This just goes to show how much more skill may be gained when one is willing to put in the hard work to learn it. Offscreen canvas and the related technology should be used at any opportunity to make efficient graphics processing!