One of the intresting useful feature of HTML5 is webworkers. Webworkers are helpful to create responsive and high computational applications. It solves many issues regarding performance of apps and high computations with less resources, we can easily migrate to webworkers to get more performance by implementing apps with webworkers. The blocking of UI and getting the kill pages and Aw,snap massages will no longer exists.
workers
webworker specification api allows the authors to run the scripts in background indepandantly without affecting user interface scripts. webworkers runs like thread. computing in webworkers will give high performance to app.webworker support checking
Major user agents IE10.0,FF3.5+,chrome 4.0+,Safari6.0+,Opera10.6+ supports webworkers. Programatically checking webworker support.if(window.Worker) { console.log('webworker support'); } else{ console.log('Oops! no webworker supprt'); }
Types of webworkers
We have two kinds of workers. They areDedicated workers: it has global access, same for all the documents.
Shared workers: it has ports access, changes with the connection.
*This part covers dedicated workers and the shared workers are covered in next part.
Defining worker
We can define the workers in two waysexternal workers
Inline workers/embended workers
External workers
Defining workers needs a url to communicate with the script through transferable objects. This example just demonstrate worker initialization.var worker= new Worker('worker_script.js'); // This defines worker script path to connect
Communication with worker
when postMessage() is called worker handles the data with onmessage() event and it will perform the operations on recieved data. The below code is to send message to worker.worker.postMessage("Hi this is raju"); //this is to send message
Handling messages in workers
When message recieved from main page the onmessage event handles data. This example is to handling messages in workers***** worker_script.js *****
onmessage=function(e){ //Handle the messages with event var data=e.data; //this is the data recieved from UI }
Sending messages from workers
postmessage() is to sending the messages to UI. This code to send message from worker.onmessage-function(e){ var data=e.data; //recieved data postMessage('This is recieved message'+e.data); //sending message to UI }
Handling worker Messages
worker messages are handle in UI using worker onmessage event. The code just handle messages of workers.worker.onmessage=function(e){ var worker_data=e.data; // recieved data from worker alert(worker_data); }
Handling Errors in workers:
worker returns the error lineno, filename, message. The code displays lineno, filename and message.worker.onerror=function(e){ console.log( 'ERROR: Line '+ e.lineno+ ' in '+ e.filename+ ': '+ e.message); }
Finally a simple example of using worker. This Example exibhits how sending messsage to worker and message from worker.
**** UI script ****
var worker= new Worker('worker_script.js'); // This defines worker script path to connect worker.postMessage("Hi this is raju"); //this is to send message worker.onmessage=function(e){ var worker_data=e.data; // recieved data from worker alert(worker_data); } worker.onerror=function(e){ console.log( 'ERROR: Line '+ e.lineno+ ' in '+ e.filename+ ': '+ e.message); }
**** worker_script.js ****
onmessage-function(e){ var data=e.data; //recieved data from UI postMessage('This is recieved message'+e.data); //sending message to UI }
Structered way of message passing to workers/JSON Data handling in workers
Suppose you need to handle the multiple computations in the workers for that you need to handle the data in stuctured format i.e; json format.look at the example of handling multiple operations in the workers. This example demonstrates how to handle when multiple messages are sent to worker
**** main page ****
var worker=new Worker('worker_script.js'); worker.postmessage(JSON.stringify({'op' : 'mult', x : 4, y : 6})); worker.postmessage(JSON.stringify({'op' : 'add', x : 6, y : 9})); worker.postmessage('wrong data'); worker.onmessage=function(e){ alert(e.data) }
**** worker_script.js ****
function addNumbers(x,y) { return x + y; } function mulNumbers(x,y) { return x*y; } onmessage = function (event) { var data = JSON.parse(event.data); switch(data.op) { case 'mult': postMessage(mulNumbers(data.x, data.y)); break; case 'add': postMessage(addNumbers(data.x, data.y)); break; default: postMessage("Wrong operation specified"); } };
Here the code is for sending addition and multiple requests and processing computation in worker then return the result to main page.
workers/ Embended workers:
Inline workers can ba added in two ways one is by using createObjectURL and other is script tag type attribute worker/javascript. This example demonstrate how to add inline workers using blob and createObjectURl.var bb = new BlobBuilder(); bb.append("onmessage = function(e) { postMessage('Inline worker creation'); }"); var blobURL = window.URL.createObjectURL(bb.getBlob()); var worker = new Worker(blobURL); worker.onmessage = function(e) { alert(e.data) }; worker.postMessage();The above code initializes BlobBuilder and append it with worker code.
Then it create url for blob.
Finally Initializes the worker with generated URL.
Sub workers:
Deviding tasks among workers is the easy using subworkers. Here we are taking multiple operations and passing the objects to the main worker and it will divert the calls to subworkers.**** main page ****
var worker=new Worker('worker_script.js'); worker.postmessage(JSON.stringify({'op' : 'mult', x : 4, y : 6})); worker.postmessage(JSON.stringify({'op' : 'add', x : 6, y : 9})); worker.postmessage('wrong data'); worker.onmessage=function(e){ alert(e.data) }
**** worker_script.js ****
var thisworker=this; var add = new Worker('subworker1.js'); var mult= new Worker('subworker2.js'); add.onmessage=function(e){ thisworker.postMessage(e.data); } mult.onmessage=function(e){ thisworker.postMessage(e.data); } thisworker.onmessage = function (event) { var data = JSON.parse(event.data); switch(data.op) { case 'mult': mult.postMessage(JSON.stringify(data.x, data.y)); break; case 'add': add.postMessage(JSON.stringify(data.x, data.y)); break; default: thisworker.postMessage("Wrong operation specified"); } };
**** subworker1.js ****
onmessage=function(e) { var data=JSON.parse(e.data) var result= data.x + data.y; postMessage(result); }
**** subworker2.js ****
onmessage = function(e) { var data = JSON.parse(e.data) var result = data.x * data.y; postMessage(result); }
The above code simple sends the send the multiple messages to the main thread. Then the processing of cumputation done in subworkers.
Terminating the webworkers
Two ways you can terminate workers.From app : worker.termiante();
From worker: self.close();
Workers Not have access:
The DOMThe window object
The document object
The parent object
Importing scripts in workers
importScripts('Base64.js'); //Single scriptimportScripts('Base64.js','FileSaver.js'); //multiple scripts importing
*DOM based scripts cannot be import
**After importing total script only worker started
**imported scripts errors should be handled
Worker specific classes
FileReaderSync to read file or blob inside workerFileWriterSync to write file
RequestFileSystemSync for file system handling
IndexedDBSync in for client side database storage
DOM functions available in workers
atob() //Not in chromebtoa() //Not in chrome
dump()
clearInterval()
clearTimeout()
setInterval()
setTimeout()
Navigator object
location object
Application Cache
*Some useful APIs are not supported by webworkers like websockets,localstorage,etc..
Classes available in workers
XMLHttpRequest()Worker()
Webworkers Errors and Debugging:
Chrome developer tools has an advantage of debugging worker scripts. and you can place breakpoints, scope of variables etc... You can also use stacktrace.jsSecurity locks
Due to chrome security issues and same origin consideration, chrome doesn't allow local file access as worker script, for that you should start the chrome with the flag --allow-file-access-from-files or you need to run the app from your local host.Things you should keep in mind the objects cannots be passed through webworkers if you try to do this. You will get DATA_CLONE_ERR DOM Exception 25.
Some API's are not supported in workers, if you try to pass or access unsupported API's in webworkers, you will get SECURITY_ERR DOM Exception 18.
If You want pass the objects to the workers,you should use JSON.stringify for object to string and JSON.parse or eval() for String to object.
HTML5 File Transfer using webworkers and XHR2 is demonstrated here.
Further reading :
1 comments:
commentsI think that in the support checking code it should be window.Worker.
Reply