Web Workers are a simple JavaScript API that allow for background threads to be run while the user experience/interface is left uninterrupted. Web Workers are passed messages by the main script, run their process with that message and then return a message back to the main script to be used.
In this simple example I use the problem of finding all the multiples of 3 or 5 between an upper and lower bound, counting how many of them there are and then adding all those numbers together. This example can be computationally heavy enough to take some time, and during that time I have a spinning loading icon from Font Awesome display to illustrate how the user interface remains uninterrupted during the computation.
HTML
The HTML of this example is pretty simple. I have included an explanation of what’s going on along with the text input that we will get our upper and lower bounds from. There is also a button to execute the calculation along with a paragraph for the loading icon and another paragraph for the results to be displayed to.
One thing to note about this HTML is that the main script.js
is linked at the very bottom of the page. Think of jQuery as an example where you need the document to be ready before you can do anything, this pretty much accomplishes the same task and it’s likely your script won’t work unless it’s at the bottom of the page.
The very minimal CSS for this page can also be found below, but feel free to leave it out if you don’t want to use it. All it does it make the page look a little better but it won’t affect your Web Worker.
The Main Script
The contents of script.js
can be found below. This script gathers the upper and lower bounds from the HTML and then passes those values to the worker. You can see that a worker is created by calling the new Worker( … )
constructor and passing it a named Javascript file. This file will contain all your worker code that will be run in the background thread (we will get to this file next).
You can run whatever code you like inside the worker thread, with some exceptions. Note that you can’t directly manipulate the DOM from inside a worker, or use some default methods and properties of the window object. You can use a large number of items available under window though, including things like WebSockets.
Data is sent between the worker (worker.js
) and the main thread (script.js
) via a system of messages — both sides send their messages using the postMessage( … )
method, and both sides respond to messages via the onmessage
event handler. This makes the general workflow as follows:
script.js
sends message toworker.js
viapostMessage( … )
worker.js
receives message fromscript.js
viaonmessage
worker.js
does calculations on messageworker.js
sends results toscript.js
viapostMessage( … )
script.js
receives results fromworker.js
viaonmessage
The code can all be seen below:
As you can see we activate the loading icon right before the message is sent and we deactivate it right after the results are sent by the worker.
The Worker Script
The worker script is one of the simplest one’s to implement. The only thing you have to remember is to include the onmessage
event handler right at the top and then to put all your code inside of there. This is just a simple algorithm to brute force count the multiples of 3 or 5 and then to find the sum of those multiples. Once we have the calculations done we simple send the results back with the postMessage( … )
function. script.js
receives these results via onmessage
and then we can display them from the main script.
Conclusion
This article hasn’t gone into the depth of some of my other articles, but I think it’s best if you just take the code and try out the Web Worker for yourself. Change the code around and try out your own problems and you’ll quickly figure out what’s going on. Workers are relatively easy to use once you try them out. If you want to download all the files as a zip rather than copy-paste from the GitHub Gists above then click here.
As always thank you for reading and please share it around as much as you can! Please feel free to put any suggestions or ideas for future tutorials in the comments section below.