Working with Inline Web Workers
In the past I wrote a post about what are
Web Workers.
In short, Web Workers enable web developers to run JavaScript code in the background which might help to increase web page performance. This post is going
to explain what are inline Web Workers and how to create them.
Inline Web Workers
When dealing with Web Workers, most of the times you will create a separate JavaScript file for the worker to execute.
Inline Web Workers are Web Workers which are created in the same web page context or on the fly. The reason for doing such a thing is obvious, sometimes we want
to reduce the number of requests that the page perform and sometimes we need to create some functionality on the fly. Executing external JavaScript files can’t help us with that.
There are two kinds of inline Web Workers:
- Page inline worker – The worker's JavaScript code is created inline inside the web page. In this case you will use a script tag with an
ID and a JavaScript/worker type.
the type will indicate to the browser not to parse the written inline JavaScript and it will refer to it as string. Here is an example for such script tag:
<script id="worker" type="javascript/worker">
postMessage('worker sent message');
</script>
Later you will be able to retrieve the script by its id and use its textContent
property to extract the worker body.
On the fly worker – The worker’s JavaScript code is provided by an external source as string.
In both of the cases, in order to run the worker you will have to create a blob object and a blob URL.
Creating the Web Worker
The main way to create an inline Web Worker is using the BlobBuilder
object which was added by the HTML5 File API.
BlobBuilder
enables us to create a blob object from a given string. It includes two main functions – the
append
function and the getBlob
function. The append
function adds data into the underlining blob and the
getBlob
returns the created blob object.
After you create a blob object from the inline worker implementation you will have to create a URL from it. The reason is that Web Workers gets a URL as parameter. For our rescue, HTML5 defines another two functions in the File API – createObjectURL
and revokeObjectURL
. Both of the functions exists in the
window.URL
object. Blob URLs are a unique URL which is created and stored by the browser up until the document is unloaded. The
createObjectURL
function gets a blob object and returns the blob URI which can be used. The
revokeObjectURL
function is used to release a created blob URL. If you are creating a lot of blob URLs you should use the
revokeObjectURL
in order to release references to blob URLs which aren’t in use.
Let's take a look at an example of creating an inline Web Worker:
var bb = new BlobBuilder();
bb.append(workerBody);
var workerURL = window.URL.createObjectURL(bb.getBlob());
var worker = new Worker(workerURL);
In the example, a BlobBuilder
is created and a workerBody
is appended to it. The
workerBody
can be any piece of code that you want to run inside a Web Worker. After you create the in-memory blob you will use the
createObjectURL
function to create the the blob URL and use it as a parameter to the Web Worker. If you want to use the script tag from the first code example you can write the following code:
var bb = new BlobBuilder();
bb.append(document.querySelector('#worker').textContent);
var workerURL = window.URL.createObjectURL(bb.getBlob());
var worker = new Worker(workerURL);
The Full Example
I wanted to create an experimental code example to show how to encapsulate the previous inline Web Workers implementation inside a JavaScript object and use it so here it goes:
<!DOCTYPE html>
<html lang="en">
<head>
<title>Inline WebWorker</title>
<meta charset="utf-8" />
<script>
var workerHelpers = workerHelpers || {};
var BlobBuilder = window.BlobBuilder || window.WebKitBlobBuilder || window.MozBlobBuilder;
window.URL = window.URL || window.webkitURL;
workerHelpers.InlineWorkerCreator = function () {
};
workerHelpers.InlineWorkerCreator.prototype = function () {
createInlineWorker = function (workerBody, onmessage) {
if (BlobBuilder) {
var bb = new BlobBuilder();
bb.append(workerBody);
var workerURL = window.URL.createObjectURL(bb.getBlob());
var worker = new Worker(workerURL);
worker.onmessage = onmessage;
return workerURL;
}
else {
console.log('BlobBuilder is not supported in the browser');
return;
}
},
releaseInlineWorker = function (workerURL) {
window.URL.revokeObjectURL(workerURL);
};
return {
createInlineWorker: createInlineWorker,
releaseInlineWorker: releaseInlineWorker
};
} ();
window.addEventListener('DOMContentLoaded', function () {
var creator = new workerHelpers.InlineWorkerCreator();
var workerURL = creator.createInlineWorker('postMessage(\'worker sent message\');', function (e) {
console.log("Received: " + e.data);
});
console.log(workerURL);
setTimeout(function () { creator.releaseInlineWorker(workerURL); }, 1000);
}, false);
</script>
</head>
<body>
</body>
</html>
Summary
In the post I explained the reason to create inline Web Workers. I also showed how to create an inline Web Worker and provided an implementation for a JavaScript
object that can be used to do that.
I’ll appreciate any comments about the provided code.
Gil Fink is a web development expert and ASP.Net/IIS Microsoft MVP. He is the founder and owner of sparXys. He is currently consulting for various enterprises and companies, where he helps to develop Web and RIA-based solutions. He conducts lectures and workshops for individuals and enterprises who want to specialize in infrastructure and web development. He is also co-author of several Microsoft Official Courses (MOCs) and training kits, co-author of "Pro Single Page Application Development" book (Apress) and the founder of Front-End.IL Meetup. You can read his publications at his website: http://www.gilfink.net