Table of Contents
- Web Workers
- The Problem
- Code Descriptions
- Other Applications
In this second installment of our series on developing HTML5
applications for AppUp, we'll look at a new feature of HTML5, Web Workers.
We'll present an application that illustrates the use of Web Workers, as
well as some other HTML5 features such as Canvas. We conclude with a discussion
of other possible applications for Web Workers.
All of the source files described in this article can be
downloaded from here.
single thread. If you need to perform some type of CPU intensive calculations,
thread or background process would solve this problem. Furthermore, modern
multicore CPUs can execute multiple threads in parallel, so we would like to
support multiple threads to make use of the hardware's capabilities.
Web Workers is a new HTML5 feature that supports multiple
threads of execution. A Web Worker is a thread which allows you to run tasks in
a background process in parallel with the main browser UI thread. A Web Worker
thread. Web Workers allows you to do things like handle computationally
intensive tasks without blocking the UI.
A common application of Web Workers is performing a
computationally expensive task without interrupting the user interface. They
can also be used for time consuming operations like network operations.
Multithreading by its very nature raises potential
synchronization problems for shared data that is accessed by multiple threads.
Because of this, Web Workers imposes some restrictions, most notably
restricting access to the DOM, window object, document object, and parent
object by Web Workers.
The example application in this article illustrates using
Web Workers to perform a CPU intensive operation, specifically, calculating
Recall that a prime number is a number greater than one that
has no positive divisors other than one and itself. Prime numbers are important
in many areas of computing such as encryption, but for our purposes it makes a
good example of a CPU intensive calculation that can illustrate the use of Web
A simple method of determining if a number is prime is known
as trial division. It consists of testing whether a given number n is a
multiple of any integer between 2 and the square root of n. If the remainder
after dividing n by the trial integer is zero, then n is not prime. There are
algorithms that are much more efficient than trial division, but for our
purposes it makes a good CPU-intensive problem to apply Web Workers to.
Our example application will compute prime numbers and
display the most recently found prime. We'll also show the elapsed time since
the calculations were started. As there is an infinite number of prime numbers,
the program will never complete. We'll provide a Stop button to stop the
calculations and a Close button to exit the application.
To show that the calculations are indeed happening in a
separate thread, we will show an animation of a clock using the HTML5 Canvas
To start, we need a standard icon file named icon.png to
satisfy the Intel AppUp™encapsulator.
We use a style sheet to get the look we want for buttons,
the text font for the results, etc. You can study this file app.css at your
Execution starts with the file index.html. As shown in
<link href="app.css" rel="stylesheet" type="text/css" />
Listing 1: File index.html Part 1
function to initially draw the stopwatch, and then declare some variables that
we will be using:
<body background="numbers.jpg" onload="stopwatch();">
var running = false;
var timerId = 0;
var seconds = 0;
Listing 2: File index.html Part 2
The remainder of the file displays the UI strings, defines a
canvas that we will use to draw an animated stopwatch, and defines the Start,
when they are clicked. Note that the elapsed time and highest prime number
<output> tags. We'll see shortly how they are hooked up to
the code that produces the results.
<h1>Web Workers Example: Prime Numbers</h1>
<h3>Press the Start button to start the calculation process.<br>
Press the Stop button to stop calculating.</h3>
<canvas id="stopwatch" width=150 height=150>Your browser doesn't support HTML5 canvas</canvas>
<h3>Elapsed time: <output id="elapsedTime"></output><br>
Highest prime number found: <output id="primeNumber"></output></h3>
<a href="#" id="Start" class="button white" onclick="startWorker()">Start</a>
<a href="#" id="Stop" class="button white" onclick="stopWorker()">Stop</a>
<a href="#" id="Close" class="button white" onclick="closeApplication()">Close</a>
Listing 3: File index.html Part 3
Now let's look at the code for main.js, shown in Listing 4
below. The functions startWorker is called when the Start button is clicked. If
the worker thread is not already running, it sets the variable running to true,
elapsed time to zero, and saves the current date and time. It calls
stopwatch.js which we will look at later.
We add an event listener for it, and set the message handler to be the function
e which we will see shortly. We set the events to go to the output tag we
defined in main.html using its identifier
primeNumber. We get the current time
and write it into the output tag field that we defined in main.html, using its
elapsedTime. Finally, we post a message to the worker to get it
running = true;
seconds = 0;
date = new Date;
worker = new Worker("worker.js");
worker.addEventListener( worker.onmessage = function(e)
date.setSeconds(seconds - 1);
worker.postMessage(); // Start worker
running = false;
worker.terminate(); // Stop worker
Listing 4: File main.js
stopWorker functions is called when the Stop button is
clicked. It sets the variable running to false and stops a timer (which we
init() was called, as we'll see later). It then terminates the Web
Worker. This is important as there are resources that a Web Worker uses that
are freed only when it is terminated. The
closeApplication function, called by
the Close button, simply closes the application.
Now let's look at the file worker.js, shown in listing 5.
The message handler function in this file is run in the background by a
numbers starting from 2 using the method of trial division. When a prime number
is found, it posts a message passing the number as an argument. That gets
written to the output field we set up in main web page.
addEventListener('message', onmessage, false);
onmessage = function(e)
var n = 1;
n += 1;
for (var i = 2; i <= Math.sqrt(n); i += 1)
if (n % i == 0)
continue search; postMessage(n);
Listing 5: File worker.js
The final file is stopwatch.js, shown in Listing 6. The
first function in the file is init. This was called from
startWorker. It first
calls the function stopwatch and then creates a timer that will call function
stopwatch every second.
The other function in the file, stopwatch, draws an animated
clock with a hand showing seconds. It uses the canvas element created earlier
to draw. The location of the watch hand is drawn using the values of seconds
that was earlier calculated based on the current time. The code is somewhat
long but is straightforward. You can study it at your leisure.
timerId = setInterval(stopwatch, 1000);
var elem = document.getElementById('stopwatch');
if (elem && elem.getContext)
var context = elem.getContext('2d');
context.clearRect(0, 0, 150, 150);
context.rotate(-Math.PI / 2);
context.strokeStyle = "grey";
context.fillStyle = "white";
context.lineWidth = 6;
context.lineCap = "square";
context.lineWidth = 5;
for (i = 0; i < 60; i++)
if (i % 5 != 0)
context.rotate(Math.PI / 30);
for (var i = 0; i < 12; i++)
context.rotate(Math.PI / 6);
context.fillStyle = "black";
context.rotate(seconds++ * Math.PI / 30);
context.lineWidth = 6;
context.lineCap = "round";
context.strokeStyle = "red";
context.arc(0, 0, 10, 0, 2 * Math.PI, false);
context.strokeStyle = "#417FA1";
context.lineWidth = 10;
context.arc(0, 0, 140, 0, 2*Math.PI, false);
Listing 6: File stopwatch.js
Figure 1 shows a screen shot of the application running:
Figure 1: The Running Application
As there are an infinite number of primes, the algorithm
will never complete. Our example program will eventually fail when the values
floating point number loses precision such that incrementing the value by one
returns the same value. This won't happen until after many hours of execution.
For a CPU intensive application, you may think that using an
timed how long it took the the Web Workers application to calculate the primes
up to 10 million. I compared that to a native C++ program that used the same
algorithm to calculate primes. The HTML5 application took about 2 minutes to
calculate the primes between 1 and 10 million. The C++ program took about 35
seconds on the same hardware. It was a somewhat unfair comparison because the
HTML5 program also needed to perform output of the results in a nice format.
performance as the native code.
If you need to optimize performance using native code, one
alternative is a hybrid application that has both browser (HTML5) code and
native code. This, of course, will sacrifice portability.
Some other areas where Web Workers could be useful are the
performing network input/output in the background
rich text (e.g source code) syntax highlighting
image processing of data extracted from the
updating a client-side database
In this article we introduced the HTML Web Workers feature.
We showed a simple example application using Web Workers and discussed some
more realistic real-life examples of where they could be applied.