Web Workers

a-plus-forms - A+ forms. Would use again - Interview with Nikolay Nemshilov

Web workers allow you to push work outside of main execution thread of JavaScript making them convenient for long running computations and background work.

Moving data between the main thread and the worker comes with communication-related overhead. The split provides isolation that forces workers to focus on logic only as they cannot manipulate the user interface directly.

The idea of workers is valuable on a more general level. parallel-webpack uses worker-farm underneath to parallelize webpack execution.

As discussed in the Build Targets chapter, webpack allows you to build your application as a worker itself. To get the idea of web workers better, you'll learn how to build a small worker using worker-loader.

Setting Up Worker Loader#

To get started, install worker-loader to the project:

npm install worker-loader --save-dev

Instead of pushing the loader definition to webpack configuration, you can use inline loader definitions to keep the demonstration minimal. See the Loader Definitions chapter for more information about the alternatives.

Setting Up a Worker#

A worker has to do two things: listen to messages and respond. Between those two actions, it can perform a computation. In this case, you accept text data, append it to itself, and send the result:

app/worker.js

self.onmessage = ({ data: { text } }) => {
  self.postMessage({ text: text + text });
};

Setting Up a Host#

The host has to instantiate the worker and the communicate with it. The idea is almost the same except the host has the control:

app/component.js

import Worker from "worker-loader!./worker";

export default () => {
  const element = document.createElement("h1");
  const worker = new Worker();
  const state = { text: "foo" };

  worker.addEventListener("message", ({ data: { text } }) => {
    state.text = text;
    element.innerHTML = text;
  });

  element.innerHTML = state.text;
  element.onclick = () => worker.postMessage({ text: state.text });

  return element;
};

After you have these two set up, it should work. As you click the text, it should mutate the application state as the worker completes its execution. To demonstrate the asynchronous nature of workers, you could try adding delay to the answer and see what happens.

webworkify-webpack is an alternative to worker-loader. The API allows you to use the worker as a regular JavaScript module as well given you avoid the self requirement visible in the example solution. webpack-worker is another option to study.

Conclusion#

The important thing to note is that the worker cannot access the DOM. You can perform computation and queries in a worker, but it cannot manipulate the user interface directly.

To recap:

  • Web workers allow you to push work out of the main thread of the browser. This separation is valuable especially if performance is an issue.
  • Web workers cannot manipulate the DOM. Instead, it's best to use them for long running computations and requests.
  • The isolation provided by web workers can be used for architectural benefit. It forces the programmers to stay within a specific sandbox.
  • Communicating with web workers comes with an overhead that makes them less practical. As the specification evolves, this can change in the future.

You'll learn about internationalization in the next chapter.

Previous chapterDynamic Loading

This book is available through Leanpub (digital), Amazon (paperback), and Kindle (digital). By purchasing the book you support the development of further content. A part of profit (~30%) goes to Tobias Koppers, the author of webpack.

Need help?