smart | Webentwicklung
Alles rund um HTML5, PHP, WordPress & Co.

Einführung in die HTML5 Web Worker API

15. September 2013
Stephan
Einführung in die HTML5 Web Worker API

Eine HTML5 Technologie, die ich als Webentwickler absolut genial finde, ist die HTML5 Web Worker API.

Bisher war es so, dass JavaScript im Webbrowser immer nur in einem Thread, dem sogenannten Haupthread bzw. UI-Thread, ausgeführt werden konnte. Das hat den Nachteil, dass rechenintensive und zeitaufwendige Aufgaben die Benutzeroberfläche des Webbrowsers blockieren können und Nutzer ggf. auf die fertige Abarbeitung warten müssen.

Mit der HTML5 Web Worker API besteht nun die Möglichkeit weitere Threads zu erzeugen und solche Aufgaben in Hintergrundprozesse auszulagern. Dadurch ist natives Multithreading im Webbrowser möglich, wodurch wir die Bearbeitung von Aufgaben nicht nur auslagern sondern auch parallelisieren können.

Wenn ihr mehr über die HTML5 Web Worker API erfahren wollt, dann empfehle ich euch diesen Artikel durchzulesen.

Worum handelt es sich bei einem Web Worker?

Bei einem Web Worker handelt es sich vereinfacht gesagt um eine JavaScript-Datei die im Hintergrund in einem isolierten Thread ausgeführt wird. Jeder erzeugte Web Worker repräsentiert dabei genau einen Thread.

Sobald ein Web Worker erzeugt wurde, können der sogenannte Host-Thread, also der Thread, in dessen Kontext der Web Worker erstellt wurde, und der Worker-Thread selbst über das Senden von asynchronen Nachrichten miteinander kommunizieren. Bei dem Host-Thread muss es sich dabei nicht notwendigerweise immer um den UI-Thread handeln, da Web Worker selbst auch weitere Web Worker, sogenannte SubWorker, erstellen können.

Generell gibt es zwei Arten von Web Workern:

  • Dedicated Worker: Jede Instanz verfügt über eigenen isolierten Geltungsbereich. Außerdem ist Zugriff auf einen Dedicated Worker nur innerhalb des Skripts und dem Webbrowser-Tab bzw. Fenster möglich, in dessen Kontext jener Web Worker
    erstellt wurde.
  • Shared Worker: Auf eine Instanz kann innerhalb von verschiedenen Skripten und auch verschiedenen Webbrowser-Tabs bzw. Fenstern zugegriffen werden.

Limitierungen von Web Workern

Aus Gründen der Threadsicherheit ist innerhalb von Web Workern der Zugriff auf die standardmäßig im Webbrowser verfügbaren JavaScript-Funktionen limitiert. Auf folgende Funktionen bzw. Objekte kann nur zugegriffen werden:

  • navigator
  • location (schreibgeschützt)
  • XMLHttpRequest
  • atob & btoa
  • setTimeout, clearTimeout, setInterval & clearInterval
  • dumb
  • applicationCache (Application Cache API), aber gilt nur für Shared Worker
  • importScripts
  • Worker (zum Erzeugen von Sub Workern)
  • File API, FileSystem API & Indexed Database API

Dedicated Worker erstellen & mit diesem kommunizieren

Um einen Dedicated Worker zu erstellen, dient folgender Code:

var worker = new Worker('complex-calc.js');

In diesem Fall wird der sich in der complex-calc.js-Datei befindliche Code in einem separaten Thread ausgeführt.

Bevor wir dem Web Worker nun eine Nachricht senden, wollen wir zuvor noch den onmessage-Event-Handler implementieren:

worker.onmessage = function(event)
{
    console.log('Nachricht vom Worker: ' + event.data);
}

Somit können wir nun auf eingehende Nachrichten, die vom Web Worker gesendet worden, reagieren. In diesem Fall geben wir die Nachricht bzw. die gesendeten Daten einfach in der Konsole aus.

Möchten wir dem Web Worker nun eine Nachricht senden, verwenden wir die postMessage-Funktion:

worker.postMessage(
{
   type: 'startCalc',
   numOfRuns: 3
});

Hier senden wir dem Web Worker z.B. ein JSON-Objekt als Nachricht. Zwecks Threadsicherheit werden hierbei aber nie Referenzen gesendet, sondern immer nur Kopien von Daten.

Implementierung der complex-calc.js

Wie im Host-Code können wir im Code der innerhalb des Web Workers ausgeführt wird, einen onmessage-Event-Handler implementieren:

self.onmessage = function(event)
{
    if(event.data.type && event.data.type === 'startCalc')
    {
        self.doCalc(event.data.numOfRuns);
    }
}

Mit der postMessage-Funktion können wir dann auch Nachrichten aus dem Web Worker heraus zum Host-Thread senden:

self.onmessage = function(event)
{
    if(event.data.type && event.data.type === 'startCalc')
    {
        var result = self.doCalc(event.data.numOfRuns);
        self.postMessage(result);
    }
}

Innerhalb eines solchen Web Workers können wir mittels importScripts zudem weitere JavaScript-Dateien laden.

Für alle verfügbaren Funktionen und dazugehörigen Beschreibungen, solltet ihr euch mal die Spezifikation zur HTML5 Web Worker API ansehen.

Beispiel zur parallelen Ausführung von JavaScript

Damit ihr die HTML5 Web Worker API auch in Aktion sehen bzw. ausprobieren könnt, habe ich mal eine einfache Beispieldemo implementiert:

Beispieldemo: Primzahlberechnung

Mit dieser Demo könnt ihr euch alle Primzahlen in einem bestimmten Intervall berechnen lassen. Dabei könnt ihr angeben, wie viele Web Worker und somit wie viele Threads zur Berechnung verwendet werden.

Probiert z.B. mal aus, wie lange bei euch die Berechnung aller Primzahlen im Bereich von 0 bis 90.000 bei Einsatz von 0 und 4 Web Workern dauert. Beim Einsatz von 0 Web Workern ist es so, dass der Hauptthread alle Primzahlen synchron berechnen muss. Sobald ihr aber 4 Web Worker nutzt, wird die Berechnung auf 4 Threads aufgeteilt:

  • Thread Nr.1: 0 – 22.500
  • Thread Nr.2: 22.501 – 45.000
  • Thread Nr.3: 45.001 – 77.500
  • Thread Nr.4: 77.501 – 90.000

Wenn euer PC bzw. euer Notebook 4 Threads gleichzeitig bzw. parallel bearbeiten kann, dann werdet ihr im Vergleich zur Berechnung mit 0 Web Workern einen erheblichen Performance-Gewinn feststellen können.

Browser-Unterstützung

Im Gegensatz zu einigen anderen HTML5 Technologien bzw APIs, wie z.B. die HTML5 Indexed Database API, wird die HTML5 Web Worker API bereits in allen gängigen Webbrowsern unterstützt. Wobei das nur für die Dedicated Worker API gilt, denn die Shared Worker API ist bisher noch nicht in allen Webbrowser verfügbar.

Eine hilfreiche Browser-Übersicht findet ihr auf caniuse.com.

Vor- & Nachteile

Im Folgenden mal kurz und kompakt die wesentlichen Vor- und Nachteile der HTML5 Web Worker API:

Vorteile:

  • einfach zu implementierende API
  • Dedicated Worker in allen gängigen Webbrowsern verfügbar
  • ermöglicht Multithreading im Webbrowser

Nachteile:

  • innerhalb von Worker-Threads nur eingeschränkter Zugriff auf standardmäßige JavaScript-Funktionen
  • Starten bzw. Instanziieren eines Web Workers kostet zusätzliche Zeit
  • jeder Web Worker verbraucht zusätzliche Systemressourcen
  • Shared Worker bisher nicht in allen gängigen Webbrowsern verfügbar

Mögliche Anwendungsfälle

Der Einsatz der HTML5 Web Worker API eignet sich generell für alle rechenintensiven sowie zeitaufwendigen Aufgaben. Einige mögliche Anwendngsfälle wären z.B.:

  • komplexe mathematische Berechnungen, wie z.B. bei Verschlüsselungsalgorithmen
  • Textanalyse/-formatierung in Echtzeit, wie z.B. für „on the fly“ Syntax Highlighting oder Rechtschreibüberprüfung
  • Bildbearbeitung
  • Datensynchronisation, welche z.B. im Kontext von offline-fähigen Webapplikationen nötig ist

Weiterführende Informationen

Zum Abschluss möchte ich euch noch drei lesenswerte Artikel zum Thema HTML5 Web Worker API empfehlen:

Fazit

Mithilfe der HTML5 Web Worker API können rechenintensive als auch zeitaufwendige Aufgaben in Hintergrundprozesse ausgelagert und ggf. parallelisiert werden. Dadurch lassen sich bestimmte Aufgaben im besten Fall schneller verarbeiten und unnötige Wartezeiten und Blockierungen der Benutzeroberfläche vermeiden.

Vor allem moderne Webapplikationen, bei denen oftmals viel JavaScript-basierte Logik auf Clientseite implementiert ist, können hiervon in punkto Performance und Benutzerkomfort/-freundlichkeit profitieren.

Was haltet ihr von der HTML5 Web Worker API? Habt ihr die API schon mal ausprobiert oder nutzt ihr sie vielleicht sogar schon in euren Projekten?

Kommentare  
2 Kommentare vorhanden
1 Kaffeepads schrieb am 17. September 2013 um 13:10 Uhr

Danke für den Beitrag
Habe nur eine Frage, was ist mit dem Schreibgeschützt gemeint?
Bei:
Limitierungen von Web Workern
location ?

LG Konni

2 Stephan L. schrieb am 17. September 2013 um 18:50 Uhr

Hallo Konni,

schreibgeschützt bzw. nur lesenden Zugriff bedeutet, dass du nichts ändern kannst. Du kannst also auch nicht, wie sonst möglich das href-Attribut des location-Objekts ändern.

Grüße

Stephan

P.S. Nächstes mal bitte richtigen Namen im Formular eingeben und kein Keyword. Da denke ich immer, der- oder diejenige möchte nur einen doFollow-Link abstauben.

0 Trackbacks/Pingbacks vorhanden
Du bist herzlich eingeladen auch ein Kommentar zu hinterlassen!
Kommentar schreiben

Vielen Dank für dein Kommentar!