Page 1 of 3 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
Contents
- JavaScript Graphics
- Getting Started With Canvas
- Drawing Paths
Extract: Basic Paths Extract: SVG Paths Extract: Bezier Curves
- Stroke and Fill
Extract: Stroke Properties Extract: Fill and Holes Extract: Gradient & Pattern Fills
- Transformations
Extract: Transformations Extract: Custom Coordinates Extract Graphics State
- Text
Extract: Text, Typography & SVG Extract: Unicode
- Clipping, Compositing and Effects
Extract: Clipping & Basic Compositing
- Generating Bitmaps
Extract: Introduction To Bitmaps Extract : Animation
- WebWorkers & OffscreenCanvas
Extract: Web Workers Extract: OffscreenCanvas
- Bit Manipulation In JavaScript
Extract: Bit Manipulation
- Typed Arrays
Extract: Typed Arrays
- Files, blobs, URLs & Fetch
Extract: Blobs & Files Extract: Read/Writing Local Files Extract: Fetch API **NEW!
- Image Processing
Extract: ImageData Extract:The Filter API
- 3D WebGL
Extract: WebGL 3D
- 2D WebGL
Extract: WebGL Convolutions
<ASIN:B07XJQDS4Z>
<ASIN:1871962579>
<ASIN:1871962560>
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.
-
The code stored in myScript.js, or whatever file you specify, is loaded and set running using a new OS level thread.
-
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.
|