Categories
JavaScript Basics

Introduction to Web Workers

Spread the love

To run tasks that take a long time to complete, we need a way to run them in the background.

Web workers are the way to do that. They live in their own context within the browser. Therefore, they don’t have access to the DOM and have their own global variable, self.

A web worker can’t access the window object, but we still use many things that are parts of it like WebSockets and IndexedDB.

In this article, we’ll look at how to create a basic web worker that can send messages between workers and other scripts.


Characteristics of Web Workers

Web workers allow us to send messages between them and other scripts. Non-worker scripts can listen to messages that are emitted by workers by attaching handlers for messages.

To send messages, we use the postMessage() method. The message can be accessed via the Message event’s data property. Message event objects are passed into the event handler of the onmessage handler.

Workers can spawn new workers, as long as they are hosted within the same origin as the parent page. Workers may also use XmlHttpRequest for network I.O, with the exception that the responseXML and channel attributes on XMLHttpRequest always return null.

In addition to dedicated workers, there are also other kinds of workers:

  • Shared workers are workers that can be used by multiple scripts in different windows, IFrames, etc, as long as they’re in the same domain as the worker. They are more complex than dedicated workers in that scripts must communicate via an active port.
  • Service workers act as proxy services that sit between web apps, the browser, and the network. They are intended to create effective offline experiences. They intercept network requests and take appropriate actions based on whether the network is available.
  • Chrome workers are a Firefox-only type of worker that we can use when developing add-ons and want to use workers in extensions.
  • Audio workers provide the ability to direct scripted audio processing to be done inside a web worker context.

Photo by David Siglin on Unsplash


Creating a Simple Dedicated Worker

We can create a dedicated worker by creating a simple worker script and then have other scripts communicate with it.

For example, we can create a dedicated worker that takes values from two inputs and then compute the result by adding them and sending it back to the screen.

First, we create the HTML for getting the input values as follows:

Then, in main.js, we add keyup event handlers to the inputs to send the values to our dedicated worker as follows:

We also add the onmessage event handler to receive the message from the worker, which we’ll add to worker.js to get the message back from it in the following piece of code:

worker.onmessage = e => {  
  result.textContent = e.data;  
};

Finally, we create the worker code in worker.js as follows:

The code above gets the message from main.js, where we called postMessage. Whatever we passed to postMessage will be in the e parameter and we can get the data from there.

Then, in this file, we get the two numbers we passed in with the data property on the first line of the function.

We then check if both numbers are numbers and if they are, we add them together and then send the sum back to main.js with postMessage after we compute the sum and put the result in the workerResult string.

In the end, we should get something like the following:

As long as the dedicated worker script is in the same domain as our other scripts, it’ll run.

The Worker constructor also takes an option object with the following options:

  • type: A string specifying the type of worker to create. The value can be classic or module and defaults to classic.
  • credentials: A string specifying the type of credentials to use for the worker. The value can be omit (no credentials required), same-origin, or include. If it’s not specified, the type is class, then omit is the default.
  • name: A string specifying the identifying name for the DedicatedWorkerGlobalScope representing the scope of the worker. It’s mainly used for debugging.

The constructor will throw a SecurityError if it’s not allowed to start workers, like if the URL is invalid or the same-origin policy is violated.

  • NetworkError is raised if the MIME type of the worker script is incorrect.
  • SyntaxError is raised is the worker’s URL can’t be parsed.

Creating dedicated workers is simple. They let us run background tasks. Communication between workers and other scripts is by sending messages back and forth.

Web workers have their own context so they can’t use the window object or access the DOM.

By John Au-Yeung

Web developer specializing in React, Vue, and front end development.

Leave a Reply

Your email address will not be published. Required fields are marked *