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.
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
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.
Workers don’t have access to the DOM of the “parent” page. They can’t access any of the following:
The
window
objectThe
document
objectThe
parent
objectAnd, 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
objectThe
location
object (read-only)The
XMLHttpRequest
functionThe
atob()
andbtoa()
functions for converting Base 64 ASCII to and from binary datasetTimeout()
/clearTimeout()
andsetInterval()
/clearInterval()
dump()
The application cache
External scripts using the
importScripts()
methodSpawning other Web Workers[4]
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.)
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.
[2] http://gee.cs.oswego.edu/dl/concurrency-interest/index.html - and for more about multi-threading http://en.wikipedia.org/wiki/Multithreading_(computer_architecture) is a good place to start your exploration.
[3] Web Workers in mobile browsers - http://greenido.wordpress.com/2012/02/07/google-chrome-for-android-is-out-there/
Get Web Workers now with the O’Reilly learning platform.
O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.