Met de komst van HTML5 is de performance van Javascript erg belangrijk geworden. De browser fabrikanten hebben de laatste jaren dan ook flink ingezet op het optimaliseren van hun Javascript-engines. Echter, voor de user experience is niet alleen de snelheid van belang, maar ook hoe de Javascript commando's worden uitgevoerd. Webworkers vormen een nieuw en belangrijk onderdeel van Javascipt om ervoor te zorgen dat de User Interface goed blijft reageren.

Met de komst van HTML5 is de performance van Javascript erg belangrijk geworden. De browser fabrikanten hebben de laatste jaren dan ook flink ingezet op het optimaliseren van hun Javascript-engines. Echter, voor de user experience is niet alleen de snelheid van belang, maar ook hoe de Javascript commando's worden uitgevoerd. Webworkers vormen een nieuw en belangrijk onderdeel van Javascipt om ervoor te zorgen dat de User Interface goed blijft reageren.
UI thread
Javascript is in moderne browsers vele malen sneller dan voorheen, maar het blijft toch mogelijk dat de berekeningen die gedaan worden er voor zorgen dat de user-intface niet, of niet goed meer reageert. Normaal worden alle Javascript handelingen op 1 thread uitgevoerd. Code die op gebruikers interactie reageert en andere (lang durende) berekeningen zullen op elkaar moeten wachten. Bijvoorbeeld het uitklappen van een submenu zou kunnen vertragen als er op dat moment javascipt bezig is met een langere berekening. In een dergelijke situatie is een halve seconde storend, maar nog wel te overzien. Mocht je bijvoorbeeld met Javascript tekenen op het HTML5 Canvas dan is meer dan 30ms al een probleem.
We willen dus voorkomen dat de UI-thread (user interface thread) geblokkeerd wordt door een te lang durende berekening. En Webworkers zijn hiervoor de oplossing. Het is niet 100% hetzelfde als multi-threading, maar kan wel hiermee vergeleken worden. En nog meer goed nieuws: het is nog redelijk simpel ook!
Het aanmaken van een webworker
Een webworker is een Javascript bestand dat wordt geladen en uitgevoerd op de achtergrond. Het communiceren tussen de UI-thread en de Webworker gaat via “messages”. Het ceëeren van een webworker gaat alsvolgt:
var theWorker = new Worker(' worker.js');
De webworker wordt opgestart door er een bericht naar toe te sturen:
theWorker.postMessage();
In het ‘worker.js’ bestand staan minimaal een event-handler die bepaald wat er moet gebeuren als de webworker een bericht ontvangt:
onmessage = function (e) {
               // hier de implementatie van de webworker
               // Gebruik eventueel e.data
}
In het bovenstaande voorbeeldje zie je dat de eventhandler “e” binnen krijgt. In deze variabele zit de data die de UI-thread naar de webworker gestuurd heeft. Deze data kan de UI-thread meegeven via de “postMessage” functie. Je kunt hier vanalles mee geven: strings, integers, arrays, objecten, enz.
theWorker.postMessage(someData);
Communicatie terug
Omdat de webworker losstaat van de UI-thread is het niet mogelijk om elementen in de HTML-DOM aan te spreken. Of te wel, rechtstreeks een canvas element (of willekeurig ander element) manipuleren vanuit de WebWorker is onmogelijk. Het is dan de bedoeling dat we de berekening door de Webworker laten plaats vinden en de maniplulatie van de HTML-DOM door de UI-Thread. De UI-Thread zal dus weer informatie terug moeten krijgen van de Webworker. De manier om deze informatie terug te geven aan de UI-thread is óók doormiddel van berichten.
JSON parameters
Soms wil je meer dan 1 parameter meegeven aan de webworker. Dit kun je bereiken door JSON te gebruiken (Javascript Object Notation).
theWorker.postMessage({'cmd': 'raise', 'value': 10});
In de worker kun je die parameters alsvolgt uitlezen:
onmessage = function (e) {
               var data = e.data;
               var cmd = data.cmd;
                var val = data.value
               if (cmd == 'raise'){
                               val++;
               }
}
Compleet voorbeeld
Hieronder volgt een voorbeeld waarin ik een Webworker gebruik om een HTML5 Canvas element te analiseren. Aangezien een Canvas uit veel pixels kan bestaan zou dit een flinke berekening kunnen zijn en wil ik dit graag op de achtergrond laten plaats vinden. Eerst haal ik alle pixels van een HTML5 canvas op, en geef dit door aan een Webworker. Deze zal op de achtergrond door de pixels heen lopen en opzoek gaat naar een rode pixel. Als deze gevonden is, dan retourneert hij welke pixel het was naar de UI-Thread die er vervolgens iets mee kan gaan doen.
Main.js
var canvas = document.getElementById('canvas');
var context = canvas.getContext('2d');
// haal de pixels van het canvas op
var imgdata = context.getImageData(0, 0, canvasWidth, canvasHeight);
var pixels = imgdata.data;
// creëer WebWorker
var worker = new Worker('PixelFinder.js'); 
worker.onmessage = function(e) {
//bereken x en y positie
var pixelNumber = e.data;
y = (pixelNumber / 4) / canvasWidth;
x =((pixelNumber / 4) % canvasWidth;
}; 
worker.postMessage(pixels);
PixelFinder.js
onmessage = function (e) {
var pixels = e.data;
var pixelCount = findColor(pixels);
postMessage(pixelCount);
}
function findColor(pixelData){
for (var i = 0; i < pixelData.length; i += 4) { // 4 bytes per pixel
var r = data[i]; //red
               var g = data[i + 1]; //green
               var b = data[i + 2]; // blue
               if (r == 255 && b ==0 && g == 0){
                               return i;
               }
}
}
Mitsen en Maren
Net als de andere onderdelen van HTML5, zijn er steeds meer browsers die Webworkers ondersteunen. Chrome, Firefox en Safari ondersteunen het nu al. Internet Explorer 9 helaas nog niet, maar IE10 zal het zeker wel ondersteunen. Deze browser is nog niet officieel uit, maar wel al te gebruiken / testen: http://ie.microsoft.com/testdrive/
Windows 8 Metro-style apps kunnen ook door middel van HTML5 gebouwd worden. Als je kiest voor HTML5 i.p.v. C# of VB.Net zal dit vaak zijn omdat je de multimediale kwaliteiten van HTML5 wilt gebruiken zoals het Canvas. Om deze applicaties goed te laten reageren (“responsive”) is het gebruik van Webworkers dus ook van groot belang. Dus of je nu voor web of Windows 8 ontwikkeld: Webworkers is een must.