Web Workers Basics

Excerpt

Scripts must not only be part of the document loaded in the browser. Scripts can also be loaded and launched into Workers and run in the background in a more independent way.

Workers are supported by all current browsers and provide another possibility on implementing long running processes in a way the do not freeze the UI.

Here some basic observations.

3 types of Workers

Be aware that there are multiple kind of background workers actually existing and they provide different functionalities for different purpose.

Worker -- JavaScript executing in parallel to the UI. The communication is done using Events with postMessage and onMessage.

SharedWorker -- JavaScript executing in parallel to the UI that can be used by multiple windows or browser context in parallel. The communication is done using ports and also Events with postMessage and onMessage.

ServiceWorker -- JavaScript background worker that must be installed with agreement of the user. It continues running even when the browser context is closed. It requires a secure context (https).

Worker threads

Workers run in separate threads so they can execute in parallel to the script that runs in the browser frontend. You can e. g. create a long running calculation in workers.

Also the way of communication is using an asynchronous pattern by sending messages between the browser script and the worker script.

Here you see how the 2 independent processes in the browser look like:

 Worker threads in debugger

Global Variables

As the workers do not run in the Frontend part of the browsers there is no way to access the UI Document objects from a worker.

The `window` object is not available. Eventually trying to access it throws an ReferenceError. The same is with the `document` object.

This is a problem with script and libraries that implies that they run in a bowser so don't assume that npm libraries are all working in workers.

Creating a local Worker

To create a Worker a new Worker(url) object can be created. The URL provided will be loaded in for the background thread.

ZTo create a local worker the script must not be given by a url from the server. Workers can be created also by local URLs using a non parsed script tag containing the worker code:


<script type="text/js-worker">
  // This script WON'T be parsed in teh UI by JS engines because its MIME type is text/js-worker.
  // it will be loaded into a background worker thread by a local url (see below)

  console.info('worker:', 'start...');
  postMessage('worker:start');

  setInterval(function () {
    postMessage(new Date().toISOString());}, 3000);
</script>
    

to load the script into the worker the following script does the trick:


// get all script for the worker
const workerScript =
  Array.from(document.querySelectorAll('script[type=\'text\/js-worker\']'))
    .map(oScript => oScript.textContent);
const blob = new Blob(workerScript, { type: 'text/javascript' });

// create a local URL
const url = window.URL.createObjectURL(blob);

// Creating the worker and make it accessible using the global _worker variable
_worker = new Worker(url);
    

In the following potput you see the current time from the worker in the background passed to the frontendusing a message and event:

.

Next

Some more examples will follow on the other worker types and topics.

See Also

Tags

JavaScript