Working with Inline Web Workers

January 29, 2012

one comment

Working with Inline Web Workers


Working with Inline Web WorkersIn 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. The 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.


Lets 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>
        // create a namespace for the object
        var workerHelpers = workerHelpers || {};
        
        // set the blob builder and window.URL according to the browser prefix if needed
        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);
 
            // release the URL after a second
            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.


Add comment
facebook linkedin twitter email

Leave a Reply

Your email address will not be published.

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

*

one comment

  1. jeanccMarch 29, 2017 ב 15:53

    Have you tried to access to indexedDB from the inline worker ?

    I post a question in Stackoverflow , there is some problem in chrome accesing indexedDB form blob code (the title is ‘Accessing indexedDB from code inside a Blob’)

    Reply