DCSIMG
January 2012 - Posts - Gil Fink's Blog

Gil Fink's Blog

Fink about IT

News

Microsoft MVP

My Facebook Profile My Twitter Profile My Linkedin Profile

Locations of visitors to this page

Creative Commons License

Disclaimer
The opinions expressed herein are my own personal opinions and do not represent my employer's view in anyway.
© Copyright 2012 Gil Fink

Hebrew Articles

Index Pages

My OSS Projects

English Articles

January 2012 - Posts

Working with Inline Web Workers

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.

Quick Tip – JavaScript Namespaces

Quick Tip – JavaScript Namespaces

Namespaces (or named scopes) are widely used in many programming languages. Namespaces help to group a set of identifiers into a logical group. An identifier can be a named class, named interface or any other language element that is contained inside the namespace. Since the same identifier can be used in more than one namespace but with a different meaning, using namespaces can help reduce name collisions.

Creating a JavaScript Namespace

JavaScript doesn’t include namespaces. On the other hand, JavaScript includes function scopes which means that every function which is created in the JavaScript global scope holds its own scope. With this information in mind, we can mimic namespace scope by creating a function scope. Doing so will help to reduce the number of objects associated with the global scope and help to avoid collisions between identifiers created for an application when using external libraries for example. Here is an example of creating a JavaScript namespace using a function scope:

var ns = ns || {};

The code uses a simple check whether the namespace was declared previously. If the namespace was declared the left side of the statement is evaluated and the ns variable will include the previously defined namespace. If the namespace wasn’t declared previously a new object literal (which is another way to create a function in JavaScript) will be created and be set to the ns variable.

Using a JavaScript Namespace

In the previous example a namespace was declared. In order to use the namespace you will use its name and create objects/functions inside of it. Here is an example of setting a simple object inside of the previously created namespace:

ns.Game = function (id, name, description) {
    this.id = id;
    this.name = name;
    this.description = description;
};

Now if you want to use the Game object you will create it using its namespace and it name. Here is an example for that:

var game = new ns.Game(1, 'Kinectimals', 'Raise your own cub inside this popular Kinect game');

Summary

Namespaces in JavaScript can help to organize your code into more logical groups/modules. One aspect of using this method is the reducing of objects inside the JavaScript global scope.

Posted: Jan 27 2012, 04:40 PM by Gil Fink | with no comments |
תגים:,

Build Modern Web Applications with HTML5, CSS3 and JavaScript Session – Round Three

Build Modern Web Applications with HTML5, CSS3 and JavaScript Session – Round Three

Build Modern Web Applications with HTML5, CSS3 and JavaScript Session – Round ThreeOn October 31 and December 26 last year, I delivered the “Build Modern Web Applications with HTML5, CSS3 and JavaScript” MSDN session. Since both of the sessions were fully booked, I’m going to deliver the same session on February 9 at Microsoft HQ and give those who didn’t attended in the previous sessions the opportunity to hear it. If you are interested in HTML5 you can register here.

See you there!

I’m Back

I’m Back

If you are following my Blog, you could see that in the last couple of weeks I disappeared a little. This post is being written just to let you know that I’m fine and returned to work after two weeks “vacation”. I’ll return writing posts about development soon so stay tuned.

As always, if you need my assistance you can contact me through my blog, my twitter account, or send me an email through the blog’s contact form. I’ll do my best to answer every question that you ask even if the answer is I don’t know...

Posted: Jan 19 2012, 03:54 PM by Gil Fink | with no comments |
תגים: