Javascript web workers and multithreading: Misconceptions on threading and why setTimeout is no solution

1. Introduction

!!not yet proofread.

In many situations it is useful to execute JavaScript code in parallel or "in the background". Until recently this was not possible, yet the idea presented itself that with the function setTimeout( func : function, timeout : int) a background process would be started. This has in fact not been the case. Any function delegated to setTimeout for invocation after a set amount of milliseconds (setTimeout's second parameter), is conditionally pushed to the event-based running stack of the Javascript interpreter/compiler after a given interval has passed.

This means that if the javscript code is for instance executing a loop for much longer than the planned call of the function passed to setTimeout or setInterval won't be executed until the running stack invokes the next call.

This can be demonstrated with the following simple code:

In the example above the function passed to setTimeout will write to the console after one second. Directly afterwards however a while-loop may block the . This may no longer work in newer Browsers due to radical changes of the javascript interpreters. One of the troubling moments of users browsing the web, were errantly invoked, infinite loops which could put the current browser window to a complete stall, and in fact the entire browser, due to the non-multithreaded design. All current browsers are multithreaded to lesser (Opera) or greater extend (Chrome, IE >10)

2.0 JavaScript multitasking with web-workers:

Running javascript in an own thread, forked from the running browser-application, became recently possible with web workers. Note: A thread of execution is the smallest unit of processing that can be scheduled by an threaded operating system.

Web workers are dedicated threads running Javascript compilers, executing  defined javascript code in the background and require the use of special functions only recently introduced (Opera >10.6, Chrome >3, FireFox > 3.5, Safari >4, Internet Explorer > 10) but are widely supported now. The nature of such web workers implies a high memory footprint, and a slightly higher cost in computation. As such they are not intended to be used in high numbers, but for Javascript applications that need to address the need for multitasking.

There are two principle types:
  • Dedicated workers: The script can instance its own dedicated thread, at the cost of higher memory consumption and in fault cases, memory-leak-like effects.
  • Shared workers: All the scripts can delegate their background tasking needs to one pooled background web-worker thread. Shared worker objects are within the scope of where they originated (Where instancing took place) .

2.1 Shared workers:
Shared workers are created by invoking the function SharedWorker(), with the URL of the script to execute as the first parameter, and a name for the web worker as the second parameter.
Just like in any multithreaded design, specific interfaces or binding of event handlers must be used for cross-thread communication. This is facilitated with the instanced MessagePort object, returned by the SharedWorker()'s constructor upon creation. This returned MessagePort object holds a reference to the port, accessible by the property port .

2.2 Example for Shared Web Workers:

2.2 Dedicated workers:
Dedicated Web Workers are quickly created, and allow Javascript applications to be backgrounded simply by passing the URL of a Javascript file to the constructor of Worker. Workers can push messages to the parent task (caller-thread) by posting messages to it via the MessagePort method postMessage and intercept the returned message through the binding of event handlers.

The worker thread can perform tasks without interfering with the user interface. In addition, they can perform I/O using XMLHttpRequest (although the responseXML and channel attributes are always null).

2.3 Example for Dedicated Web Workers:

A the moment workers are particularly useful for computationally intensive calculations without use of Java or other third party applets and without burdening the user interface thread.

Workers are also highly limited:

  • Workers are not given access to the DOM (e.g. document, getElementsByTags, window...). Invocable are setTimeout, setInterval, and XMLHttpRequest.
  • Workers are not given access to the 'parent' document.

Provided here is an interesting demo of Simulated annealing which relies on javascript and web workers: