Learn with our tutorials and training

developerWorks provides tutorials, articles and other
technical resources to help you grow your development skills
on a wide variety of topics and products. Learn about a specific
product or take a course and get certified. So, what do you want to learn
about?

Featured products

Featured destinations

Find a community and connect

Learn from the experts and share with other developers in one of our
dev centers. Ask questions and get answers with dW answers. Search for local events
in your area. All in developerWorks communities.

HTML 5 is a very hyped technology, but with good reason. It promises to be a
technological tipping point to bring desktop application capabilities to the
browser. As promising as it is for traditional browsers, it has even more potential
for mobile browsers. Even better, the most popular mobile browsers have already
adopted and implemented many significant parts of the HTML 5 specification. In this
five-part series, you will take a closer look at several of those new technologies
that are part of HTML 5 and can have a huge impact on mobile Web application
development. In each part, you will develop a working mobile Web application
showcasing an HTML 5 feature that you can use on modern mobile Web browsers like the
ones found on the iPhone and Android-based devices.

Getting started

In this article, you will develop Web applications using the latest Web technologies.
Most of the code here is just HTML, JavaScript, and CSS—the core technologies
of any Web developer. The most important thing you will need are browsers to test
things on. Most of the code in this article will run on the latest desktop browsers
with some noted exceptions. Of course, you must test on mobile browsers too, and you
will want the latest iPhone and Android SDKs for those. In this article, iPhone SDK
3.1.3 and Android SDK 2.1 were used. This article's sample also uses a proxy server
to access remote services from the browser. The proxy server is a simple Java™ servlet,
but could be easily replaced by a proxy in PHP, Ruby, or others. See Related topics for links.

Multi-threaded JavaScript on mobile devices

Multi-threaded or concurrent programming is nothing new to most developers. It is
supported, in one way or another, in most modern programming languages. However,
JavaScript is not one of the languages that supports concurrent programming. Its
creator thought that it was too problematic and unnecessary for a language like
JavaScript that was designed for performing simple tasks on Web pages. However, as Web
pages have evolved into Web applications, the complexity level of tasks done with JavaScript has grown to put JavaScript on par with any other language. At the
same time, developers working in other languages that support concurrent programming have often suffered and struggled with the extraordinarily high complexity that comes along with concurrent primitives like threads and mutexes. In fact, recently, a number of new languages like Scala, Clojure, and F# have evolved, all promising to simplify concurrency.

Frequently used acronyms

Ajax: Asynchronous JavaScript + XML

API: Application Programming Interface

CSS: Cascading stylesheet

DOM: Document Object Model

HTML: Hypertext Markup Language

REST: Representational State Transfer

SDK: Software Developer Kit

UI: User Interface

URL: Uniform Resource Locator

W3C: World Wide Web Consortium

XML: Extensible Markup Language

The Web Worker specification is not just about adding concurrency to JavaScript and Web
browsers; it is about doing this in a smart way that will empower developers without
giving them a tool that causes problems. For example, desktop application developers
have used multi-threading for years to let their applications access I/O resources
without freezing the UI while they wait for these resources. However, such
applications often suffer when these multiple threads change shared resources
(including the UI) which leads to applications that freeze up or crash. With Web
Workers, this cannot happen. The spawned thread does not have access to the same
resources as the main UI thread. In fact, the code in the spawned thread cannot even
be in the same file as the code that is executed by the main UI thread.

You even have to supply that external file as part of the constructor, as in Listing 1.

This process uses three things:

The JavaScript for the Web page (I will call it the page script) executed
on the main thread.

The Worker object which is the JavaScript object that you use to perform the
Web Worker function.

The script that will be executed on the newly-spawned thread. I will call it the
Worker script.

Listing 1. Using a Web Worker in the page script

In Listing 1, you can see the three basic steps in using Web Workers.
First, you create a Worker object and pass it the URL of the script that will be
executed in the new thread. All of the code that the Worker will execute must be
contained in the Worker script whose URL is passed in to the constructor of the Worker. The
URL of this Worker script is limited by the browser's same origin policy—it must come
from the same domain that loaded the page that loaded the page script that is creating
the Web Worker.

The next thing you do is to specify a callback handler function using the onmessage function. This callback function will be invoked after the Worker
script executes. message is data that is returned
from the Worker script and you can do whatever you want with that message. The
callback function is executed on the main thread, so it has access to the DOM. The Worker
script runs in a different thread and does not have access to the DOM, so you need to
send data from the Worker script back to the main thread where you can safely modify
the DOM to update the UI of your application. This is the key feature of the
nothing-shared design of Web Workers.

The last line of Listing 1 shows how the Worker is initiated—by calling its postMessage function. Here you pass a
message (again, this is just data) to the Worker. Of course, postMessage is an asynchronous function; you call it and it
immediately returns.

Now, examine the Worker script. The code in Listing 2 is the contents of the worker.js file from Listing 1.

Listing 2. A Worker script

You can see that the Worker script has its own onmessage
function. This is invoked when you call postMessage from
the main thread. The data you passed from the page script is passed to the postMessage function in the message object.
You access the data by retrieving the data property of the
message object. When you finish processing the data in the Worker
script, you invoke the postMessage function to send data back to the main thread. That data is also available to the main thread by accessing the data property of the message it receives.

So far you have seen the simple, but powerful semantics of Web Workers. Next, you will see how to apply this to speed up mobile Web applications. Before getting into that, it's necessary to talk about device support. After all, these are mobile Web applications and dealing with the differences in capabilities between browsers is essential to mobile Web application development.

Device support

Starting with Android 2.0, the Android browser has had full support for the HTML 5 Web
Worker specification. At the time of writing this article, most new Android devices,
including the very popular Motorola Droid, are shipping with Android 2.1. In addition,
this feature is fully supported in the Mozilla Fennec browser available on Nokia
devices running its Maemo operating system, and on Windows Mobile devices. The notable
omission here is the iPhone. iPhone OS versions 3.1.3 and 3.2 (the versions of the OS
that run on the iPad) do not support Web Workers yet. However, this feature is already
supported on Safari, so it should just be a matter of time before it shows up on the
Mobile Safari browser running on the iPhone. Given the dominance of the iPhone
(especially in the US) it is best to not rely on Web Workers being present and only
use them to enhance your mobile Web applications when you detect that they are
present. With this in mind, look at how you can use Web Workers to make mobile Web applications faster.

Improving performance with Workers

Web Worker support on smart phone browsers is good and improving. This begs the
question: When do you want to use Workers in mobile Web applications? The answer is
simple: whenever you need to do something that takes a long time. Some Worker examples
show Workers being used to perform intense mathematical computations, like calculating
ten-thousand digits of pi. It's fairly unlikely that you will ever need to perform
such a computation on any Web application, much less a mobile Web application.
However, retrieving data from remote resources is fairly common, and that is the focus
of the example in this article.

In this example, you will retrieve a list of Daily Deals (deals that change each
day)from eBay. The deals list contains brief information about each deal. More
detailed information can be obtained by using eBay's Shopping API. You will use Web
Workers to pre-fetch this additional information while the user browses the list of
deals to pick the one of interest. To access all of this eBay data from your Web application, you will need to deal with the browser's same origin policy by using a generic proxy. A simple Java servlet was used for this proxy. It is included with the code for this article, but it is not shown here. Instead, let's focus on the code that works with the Web Workers. Listing 3 shows the basic HTML page for the deals application.

As you can see, this is a very simple piece of HTML; it is just a shell. You retrieve
the data and generate the UI using JavaScript. This is the optimal design for mobile
Web applications, since it allows for all of the code and static markup to be cached
on the device, and the user only waits for data from the server. Notice that, in Listing 3, once the body has loaded, you call the loadDeals function where you load the initial data for the
application in Listing 4.

Listing 4 shows the loadDeals function, and
the global variables used in the application. You use an array of deals plus an array
of sections. These are additional groups of related deals (for example, Deals under $10). There is also a map called dealDetails whose keys will be Item IDs (which you will get from the
deals data), and whose values are the more detailed information obtained from the eBay Shopping API.

The first thing you do is make an Ajax call to a proxy, which in turn calls the eBay
Daily Deals REST API. This gives you the list of deals as an XML document. You parse
the document in the onreadystatechange function of the
XMLHttpRequest object used to make the Ajax call. You use two other functions, parseDeal and parseSection, to parse the
XML nodes into easier-to-use JavaScript objects. You can find these functions in the
downloadable code sample (see Downloadable resources), but they are just
tedious XML parsing functions so I didn't include them here. Finally, after parsing
the XML, you use two more functions, createDealUi and createSectionUi, to modify
the DOM. When you are done, the UI looks like Figure 1.

Figure 1. Mobile Deals UI

If you go back to Listing 4, notice that after the primary deals are
loaded, you call the loadDetails function for each of the
sections of deals. In this function, you load the additional details for each deal by
using the eBay Shopping API—but only if the browser supports Web Workers. Listing 5 shows the loadDetails function.

In loadDetails, you first check for the Worker function in the global scope (the window object.) If it is not there, then you simply do nothing. If it
is there, then you first check the localStorage for the XML for this deal's details. This is a local caching strategy common to mobile Web applications, and is described in detail in Part 2 of this series (see Related topics for a link).

If the XML is found locally, then you parse it in the parseFromXml function and add the details
to the dealDetails object. If it is not found locally, then spawn a Web
Worker and send it the Item ID of the deal using postMessage. Once that Worker retrieves the data and posts back to
the main thread, you parse the XML, add the result to dealDetails, and store the XML
in the localStorage. Listing 6 shows the Worker script, details.js.

The Worker script is pretty simple. You use Ajax to call the proxy, which in turn calls
the eBay Shopping API. Once you receive the XML from the proxy, you send it back to
the main thread using a JavaScript object literal. Note that, even though you can use
XMLHttpRequest from a Worker, everything will come back on
its responseText property, never its responseXml property. That is because there is no JavaScript DOM
parser in scope within the Worker script. Note that the generateUrl function comes from the common.js file (in Listing 7). You imported common.js using the importScripts function.

Now that you have seen how to populate the deal details (for browsers that support Web
Workers), go back to Figure 1 to figure out how this is used in the
application. Notice that each deal has a Show Details button next to it. Click it to modify the UI as in Figure 2.

You are passed the ID of the deal that is going to be shown and toggle whether it is
displayed or not. When it is first called, it checks to see if the details have
already been stored in the dealDetails map. If the browser supports Web Workers, then
these details are already stored there and the UI for it is created and
added to the DOM. If the details are not loaded already, or if the browser does
not support Workers, then you make an Ajax call to load this data. This is how the
application can work equally well whether Workers are present or not. This means that,
if Workers are supported, then the data is already loaded and the UI will
respond instantly. If there are no Workers, the UI still loads, but it takes a few seconds.

Web Workers sound like an exotic new technology for Web developers. But, as you have seen in this article, they have very practical applications. This is especially true for mobile Web applications. The Workers can be used to prefetch data or perform other ahead-of-time operations to provide a much more lively UI. This can be especially true on mobile Web applications that need to load data over a potentially slow network. Combine this with caching strategies, and your users will be amazed by the snappiness of your application.

New elements in HTML 5 (Elliotte Rusty Harold, developerWorks, August 2007): HTML 5 is not just about JavaScript. Read about some of the new markup in HTML 5.

Android and iPhone browser wars, Part 1: WebKit to the rescue (Frank Ableson, developerWorks, December 2009): Do you like the mobile Web application approach using HTML 5 approach, but still want your application in the iPhone App Store and Android Market? See how you can get the best of both worlds in Part 1 of this two-part article series.

Dive Into HTML 5: Check out this free book for a great look at HTML 5 detection techniques as well as the many features of HTML 5.