Webanwendungen werden im Browser in einem einzigen Prozess ausgeführt. Falls die Anwendung rechenintensive oder sich wiederholende Operationen durchführt, kann dies zu Performance-Problemen führen oder die Stabilität des Browsers beeinträchtigen. Aus diesem Grund wurden Web Workers erfunden, die Teil von HTML5 sind. Damit können Ressourcen-hungrige Skripte ausgelagert werden, so dass sie in eigenen Prozessen laufen.
Als erstes möchte ich die “herkömmliche” Herangehensweise demonstrieren. Im folgenden Beispiel wird in regelmäßigen Abständen ein Ajax-Aufruf ausgeführt. Dieser holt die aktuelle Uhrzeit von einem PHP-Skript und schreibt das Ergebnis in ein div-Element.
<!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8" /> <title>untitled</title> <script> function sendRequest() { var httpRequest = new XMLHttpRequest(); httpRequest.open('GET', 'remote.php', true); httpRequest.onload = function() { $('result').update(httpRequest.responseText); httpRequest = null; }; httpRequest.send(null); } setInterval(function() { sendRequest(); }, 3 * 1000); </script> </head> <body> <p id="result"></p> </body> </html>
Als nächstes soll das Ganze mithilfe eines Workers umgesetzt werden. Dazu wird eine neue Datei benötigt, die ich einfach worker.js genannt habe. Der Inhalt gleicht dem obigen Skript:
function sendRequest() { var httpRequest = new XMLHttpRequest(); httpRequest.open('GET', 'remote.php', true); httpRequest.onload = function() { postMessage(httpRequest.responseText); httpRequest = null; }; httpRequest.send(null); } setInterval(function() { sendRequest(); }, 3 * 1000);
Der Unterschied liegt in der Behandlung des Ergebnisses aus dem Ajax-Aufruf. Im ersten Beispiel wurde das Ergebnis direkt ins div-Element geschrieben. Web Worker haben jedoch keinen Zugriff aufs Dokument. Stattdessen wird das Ergebnis nun per postMessage() an selbiges zurückgegeben. Im HTML-Dokument muss nun noch die Nachricht angenommen und ausgegeben werden:
var worker = new Worker('worker.js'); worker.onmessage = function(event) { $('result').update(event.data); };
Leider gibt es noch nicht so viele Browser, die diese Technologie unterstützen. Ich habe es mit Firefox 3.5.9 und Chrome 5 erfolgreich getestet. Momentan scheinen die Debugging-Möglichkeiten aber noch etwas begrenzt zu sein. So sieht man in der FireBug-Konsole nicht, dass Ajax-Aufrufe stattfinden – aber das hängt bestimmt damit zusammen, dass der Worker in einem eigenen Prozess arbeitet. In Chrome gibt es dagegen schon etwas mehr Unterstützung. Man kann dank der Zeitleiste sehen, dass worker.onmessage ausgeführt wird und zudem erscheint der Worker in Chrome’s Task-Manager.
Fazit: Ich halte dies für eine sehr interessante und notwendige Technologie. Hoffentlich wird sie in absehbarer Zeit von mehr Browsern unterstützt. Dieser Beitrag sollte allerdings nur Grundlegendes vermitteln. Web Worker haben nämlich noch weitere Funktionalitäten. So lassen sich zum Beispiel weitere Worker aus einem Worker heraus starten. Mehrere Dokumente bzw. Tabs können auf ein und den Selben Worker zugreifen. Und es lassen sich externe Skripte und somit auch Bibliotheken in Workern nutzen.
Quellen: