Top-Fragen
Zeitleiste
Chat
Kontext

Web Worker

JavaScript-Skript Aus Wikipedia, der freien Enzyklopädie

Remove ads

Web Worker führen JavaScript Code getrennt vom Hauptthread im Hintergrund aus. Web Worker gibt es in drei Typen: Dedicated Workers, Shared Workers und Service Workers.

Dedicated Workers

Zusammenfassung
Kontext

Der gewöhnliche Web Worker nennt sich Dedicated Worker.

Problem

Thumb
Warnmeldung über ein Skript, das so lange braucht, dass es nicht mehr zu reagieren scheint

Immer länger werdende JavaScript-Skripte führten Browsern nur in einem einzigen Thread im Vordergrund aus. Dies führte zunehmend zu Problemen, je umfangreicher aufwändiger Code verarbeitet werden soll, da dieser sehr lange läuft und damit in der Zwischenzeit die Interaktion des Benutzers mit der Internetseite sehr erschwert oder ganz unmöglich macht. Dagegen bieten die meisten Browser eine Möglichkeit ein viel zu lange laufendes Skript abzubrechen. In diesem Fall wird der Browser bis zum Zeitlimit durch die Skripte blockiert, wenn diese eine zu komplexe und damit sehr rechenintensive Aufgabe abarbeiten. Um diese Behinderungen zu umgehen, wurde die Web-Worker-API entwickelt.[1]

Web-Worker-API

Über new Worker( 'skript.js' ) kann ein neuer Web Worker eingerichtet werden. Der Browser lädt dazu das angegebene Skript in einen neuen Thread. Die Kommunikation mit dem Worker kann in beide Richtungen über die Methode postMessage und den Eventlistener onmessage erfolgen.

Innerhalb des Workers stehen alle JavaScript-Funktionen zur Verfügung, die im ECMAScript-Standard definiert sind, ebenso viele der browsertypischen APIs. Eine wichtige Ausnahme hiervon ist das Document Object Model. Der Worker-Code hat hierauf keinen Zugriff und muss zum Verändern der Seite daher dem Hauptthread eine Nachricht schicken, damit dieser die gewünschten Befehle ausführt.

Variablenübergabe

Über postMessage können Variablen von einfachen Typen übergeben werden, Zahlen, Zeichenketten, Arrays und einfache Objekte (etwas mehr als in JSON möglich ist). Anders als bei Übergaben an Funktionen wird dabei eine Kopie angefertigt, die Daten also als Wertparameter und nicht wie sonst üblich als Referenzparameter übergeben. Funktionen und Objekte im Sinne von objektorientiertem Code müssen dagegen für eine Übergabe geeignet serialisiert und deserialisiert werden.

Binäre Daten können als ArrayBuffer übergeben werden, anschließend ist aber kein Zugriff mehr auf das Original möglich. Alternativ kann ein SharedArrayBuffer verwendet werden, der von mehreren Threads gleichzeitig bearbeitet werden kann. Hierfür stehen besondere atomare Operationen zur Verfügung.[2]

Während DOM-Elemente nicht an einen anderen Thread übergeben werden können, soll dies für Canvas-Elemente bis zu einem gewissen Maß möglich gemacht werden. Der Hauptthread kann über ein OffscreenCanvas-Element die Kontrolle an einen Hintergrundthread abgeben, dort können alle üblichen Funktionen zum Zeichnen aufgerufen werden.[3]

Beispiel

Das folgende Beispiel sucht nach Primzahlen. Diese werden der Reihe nach in einem Worker berechnet und dem Hauptthread zur Anzeige übergeben.[4]

Das HTML-Dokument bettet dabei direkt das Hauptskript ein. Dieses erstellt einen Worker und reagiert anschließend auf Mitteilungen, die dieser Worker sendet.

<!DOCTYPE html>
<html>
 <head>
  <title>Worker-Beispiel</title>
 </head>
 <body>
  <p>Die bis jetzt größte gefundene Primzahl ist: <output id="result"></output></p>
  <script>
   var worker = new Worker( 'worker.js' ); // erzeugt neuen Worker
   worker.onmessage = function ( event ) { // wird aufgerufen, wenn Worker eine Nachricht sendet
     document.getElementById( 'result' ).textContent = event.data; // zeigt die gefundene Primzahl an
   };
  </script>
 </body>
</html>

Der Code für das Skript worker.js sucht dabei in einer Endlosschleife nach Primzahlen und teilt dem Hauptthread immer mit, wenn er eine gefunden hat:

var i, n = 1;
search: while ( true ) {
  n++;
  for ( i = 2; i <= Math.sqrt( n ); i++ ) {
    if ( n % i === 0 ) {
      continue search;
    }
  }
  // n ist eine Primzahl
  postMessage( n );
}
Remove ads

Shared Worker

Ein gewöhnlicher Worker gehört immer zu der Seite, die ihn erzeugt hat. Ruft ein Benutzer die Seite mehrfach in seinem Browser auf (oder verschiedene Seiten derselben Domain, die den gleichen Worker einsetzen), so werden mehrere Worker mit dem gleichen Code initialisiert. Setzt man stattdessen einen SharedWorker ein, so wird dieser wiederverwendet.

Service Worker

Eine weitere besondere Art eines Web Workers ist der Service Worker. Dieser wird für zwei Aufgaben eingesetzt: Zum einen kann er als Proxy fungieren, zum anderen vom Server gesendete Benachrichtigungen selbst dann empfangen, wenn gerade keine Seite der entsprechenden Domain geöffnet ist.[5]

Für die Aufgabe als Proxy steht im Worker das fetch-Event zur Verfügung, das immer ausgelöst wird, wenn der Browser Daten der überwachten Domain anfordert, unabhängig davon, ob dies durch AJAX, Benutzernavigation oder andere Ursachen ausgelöst wird. Der Worker kann das Event abfangen und bei Bedarf die angeforderten Daten auf andere Weise zur Verfügung stellen. Insbesondere sind Service Worker als Ersatz für Application Cache zur Implementierung von Web-Apps vorgesehen, die auch offline funktionieren sollen.[6] Die Spezifikation ist aber so flexibel, dass zahlreiche weitere Möglichkeiten über einen einfachen Cache hinaus möglich sind.[7]

Browserunterstützung

Browser wie Google Chrome ab der Version 4, Mozilla Firefox ab Version 3.5, der Internet Explorer ab Version 10, Edge ab Version 12 boten grundlegende Unterstützung für Web Worker.[8] Die Unterstützung wurde und wird mit neueren Versionen immer weiter ausgebaut. Service Worker waren mit Chrome ab Version 40, in Firefox ab Version 44 noch nicht im kompletten Umfang implementiert.[9]

Normen und Standards

Web Workers ist standardisiert vom W3C. Die aktuelle Spezifikation stammt vom 24. September 2015.

Einzelnachweise

Loading related searches...

Wikiwand - on

Seamless Wikipedia browsing. On steroids.

Remove ads