JavaScript Canvas - Web Workers
Written by Ian Elliot   
Tuesday, 07 June 2022
Article Index
JavaScript Canvas - Web Workers
The Trouble With Threads
Transferable Objects

Graphics needs processing power.  In this extract from Ian Elliot's book on JavaScript Graphics we look at how to get started with Web Workers to get the job done faster.

Now available as a paperback or ebook from Amazon.

JavaScript Bitmap Graphics
With Canvas




  1. JavaScript Graphics
  2. Getting Started With Canvas
  3. Drawing Paths
      Extract: Basic Paths
      Extract: SVG Paths
      Extract: Bezier Curves
  4. Stroke and Fill
      Extract: Stroke Properties 
      Extract: Fill and Holes
      Extract: Gradient & Pattern Fills
  5. Transformations
      Extract: Transformations
      Extract: Custom Coordinates 
      Extract  Graphics State
  6. Text
      Extract: Text, Typography & SVG 
      Extract: Unicode
  7. Clipping, Compositing and Effects
      Extract: Clipping & Basic Compositing
  8. Generating Bitmaps
      Extract:  Introduction To Bitmaps
      Extract :  Animation 
  9. WebWorkers & OffscreenCanvas
      Extract: Web Workers
      Extract: OffscreenCanvas
  10. Bit Manipulation In JavaScript
      Extract: Bit Manipulation
  11. Typed Arrays
      Extract: Typed Arrays **NEW!
  12. Files, blobs, URLs & Fetch
      Extract: Blobs & Files
      Extract: Read/Writing Local Files
  13. Image Processing
      Extract: ImageData
      Extract:The Filter API
  14. 3D WebGL
      Extract: WebGL 3D
  15. 2D WebGL
    Extract: WebGL Convolutions







Even if you can make your animation run fast enough, you still have the problem of the pauses that occur whenever the UI thread has to deal with something else. There are situations when your animation can freeze for a considerable time. The solution is to move the animation from the UI thread to a different thread.

Until recently there was no way that a JavaScript programmer could take advantage of the OS to schedule threads or multiple cores to implement true parallelism, but now we have web workers which implement background processing on a non-UI thread. The only problem is that a web worker cannot access the DOM and the canvas object is part of the DOM. To make it possible to implement graphics processing off the UI thread, the OffscreenCanvas object was introduced. It is still reasonably new and at the time of writing Chrome is the only browser to fully support it. While supported in Firefox, it is disabled by default and you need to set a flag to enable it, and even then it only supports the WebGL graphics context.

It is worth making clear that while OffscreenCanvas has been introduced as something to make animation smoother, almost any intensive graphics operation is better implemented as a web worker. Indeed any intensive operation of any kind is best implemented in this way.

Before we look at how to use OffscreenCanvas we need to find out the basics of using a web worker.

Basic Web Worker

The good news is that web workers are very easy to use. What is slightly difficult to get to grips with is working out what you are not allowed to do and achieving simple communication between the threads. Ideally you should wrap any web worker task you create as a Promise to make the code easier to use, but for the moment simpler is better.

There really is only one key object when using web workers, the Worker object, which automatically starts a new thread and begins executing JavaScript code as soon as it is created.

The basic action is that the worker loads the JavaScript file that you specify in its constructor and starts the script executing on a new thread. It is possible to avoid using a separate file to store the code, but it is messy and best avoided. The reason the code is in a separate file is to keep the execution contexts separated on the threads. That is, the program that starts on the new worker thread has no shared variables with the code that creates it.

So, for example, if you have a program stored in myScript.js the instruction to run it is:

var worker=new Worker("myScript.js");

Although this is simple, there is a subtlety that you need to get clear if you are to avoid making silly mistakes.

When you create a Worker object two things happen.

  1. The code stored in myScript.js, or whatever file you specify, is loaded and set running using a new OS level thread.

  2. A Worker object is created on the UI thread and this is the object that your "standard" JavaScript code running on the UI thread can use to communicate with the new worker thread.

If you think that this is obvious and doesn't need to be said, so much the better.


In the example given above worker is an object that exists on the UI thread and "myScript.js" loaded and running in isolation from the UI thread and the program that worker belongs to. Of course, the Worker object provides methods that allow communication between the two programs and this is something we have to find out how to use.

If you need to load a library into the worker thread's code you can use the importScripts function. You simply supply the URLs of the scripts to load as parameters. The scripts are downloaded in any order, but executed in the order you specify. The importScripts function is synchronous and blocks until all of the libraries have been downloaded. You can try to load standard libraries into a worker thread but, as the DOM is unavailable, they might not work. For example jQuery certainly doesn't work as it needs the DOM to function.

Last Updated ( Tuesday, 07 June 2022 )