Chapter 1. Overview

Modern web applications would often run better if there was a way to perform heavy calculations in the background instead of making the user interface wait for them to complete. The Web Workers specification[1] defines an API for running computationally intensive code in a thread other than the web application user interface. Long tasks can run without affecting your interface’s memory and CPU footprint because the Worker will live in its own thread.

Multi-threaded programing is a complicated subject well stocked with complex algorithms and theoretical discussion. You can find other languages (e.g., Java) that give their developers a library to mask some of the complexity[2]. The good news is that Web Workers provides a nice and simple API that lets you be very productive without worrying too much about deadlocks and similar problems.

Web Workers promises to end the unfriendly “unresponsive script” dialogs like the ones shown in Figure 1-1 and Figure 1-2.

The warning dialog for “unresponsive script” in Windows

Figure 1-1. The warning dialog for “unresponsive script” in Windows

The warning dialog for “unresponsive script” in MacOS

Figure 1-2. The warning dialog for “unresponsive script” in MacOS

What Can Web Workers Do?

If your web application needs to complete a task that takes more than 150 milliseconds, you should consider using a Web Worker. If your app needs to feel like a native one, you should even consider setting the bar at around 80 milliseconds. Timing, of course, depends on your browser and hardware. If you are building a mobile web application you should make this time even shorter, as the CPU is not as powerful as on your desktop.[3] Before you get into timing your specific application, though, you may want to contemplate tasks like the following:

  • Encoding/decoding a large string

  • Complex mathematical calculations (e.g., prime numbers, encryption, simulated annealing, etc.)

  • Sorting a large array

  • Network requests and resulting data processing

  • Calculations and data manipulation on local storage

  • Prefetching and/or caching data

  • Code syntax highlighting or other real-time text analysis (e.g., spell checking)

  • Image manipulation

  • Analyzing or processing video or audio data (including face and voice recognition)

  • Background I/O

  • Polling web services

  • Processing large arrays or huge JSON responses

Creating a Worker

To create a new Worker using the Web Worker API, you just need to call its script. For example:

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

The above line will load the script located at “worker.js” and execute it in the background. You need to call the Worker() constructor with the URI of a script to execute in the Worker thread. If you want to get data from the Worker (e.g., output of processed information, notifications, etc.), you should set the Worker’s onmessage property to an appropriate event handler function. For example:

var worker = new Worker('routes.js');
worker.onmessage = function(event) {
  console.log("Called back by the routes-worker with the best route to the pub");
}

You can also keep in touch with your Workers using addEventListener:

var worker = new Worker('routes.js');
worker.addEventListener('message', function(event) {
 console.log("Called back by the routes-worker... with the best route to the pub")
}, false);
worker.postMessage(); // start the worker.

What Web Workers Can and Can’t Do

Workers don’t have access to the DOM of the “parent” page. They can’t access any of the following:

  • The window object

  • The document object

  • The parent object

  • And, last but not least, they can’t use JavaScript libraries that depend on these objects to work, like jQuery.

Web Workers can access only a limited set of JavaScript’s features because of their multi-threaded nature. Here is the set of features they can use:

  • The navigator object

  • The location object (read-only)

  • The XMLHttpRequest function

  • The atob() and btoa() functions for converting Base 64 ASCII to and from binary data

  • setTimeout() / clearTimeout() and setInterval() / clearInterval()

  • dump()

  • The application cache

  • External scripts using the importScripts() method

  • Spawning other Web Workers[4]

Worker Execution

Web Workers threads run their code synchronously from top to bottom, and then enter an asynchronous phase in which they respond to events and timers. This allows roughly two types of Web Workers:

  • Web Workers that register an onmessage event handler, for long-running tasks that need to run in the background. This Web Worker won’t exit, as it keeps listening for new messages.

  • Web Workers that never register for onmessage events, handling single tasks that need to be offset from the main web app thread, like fetching and parsing a massive JSON object. This Web Worker will exit once the operation is over. (In some cases, where you have registered callbacks, it will wait until all of the callbacks are done.)

Web Workers API Browser Availability

Table 1-1 shows that most modern browsers implement basic Web Workers. Even the mobile browsers offer Web Workers. However, Table 1-2 shows less support for the shared Web Workers, which are covered in Chapter 5.

Table 1-1. Web Worker support in various browsers

Browser

Version

IE

10.0

Chrome

12+

Firefox

5+

Safari

4+

Opera

11+

iOS Safari

5+

Opera Mobile

11+

Android

2.1

Chrome for Android

Beta

Table 1-2. Shared Web Worker support in various browsers

Browser

Version

IE

Support unknown for 10.0

Chrome

12+

Firefox

Support unknown for 9+

Safari

5+

Opera

11+

iOS Safari

5+

Opera Mobile

11+

Get Web Workers now with O’Reilly online learning.

O’Reilly members experience live online training, plus books, videos, and digital content from 200+ publishers.