Javascript Web Worker • Arbeiten im Hintergrund
Javascript ist von Haus aus eine Single Threaded Programmiersprache und kann nicht zwei Aufgaben gleichzeitig durchführen. Während der Ausführung einer Aufgabe friert alles ein: Menüs, Scrollen, Downloads, der Aufbau und das Rendern der Seite sowie Animationen.
Wenn ein Script die Benutzerschnittstelle blockiert …
Web Worker führen Arbeiten im Hintergrund durch, ohne dabei die Benutzerschnittstelle zu blockieren. Da Scripte normalerweise erst ausgeführt werden, wenn die Seite vollständig geladen ist und die meisten Scripte schnell und nur in kleinen Stückchen ausgeführt werden, fallen kurze Blockaden kaum auf.
Javascript kann Aufgaben asynchron via setTimeout(), setInterval(), XMLHttpRequest oderAjax und in Event-Handlern durchführen, aber nicht parallel zu anderen Aufgaben. Eine Reihe von Javascript-Operationen wird allerdings immer synchron ausgeführt.
- Berechnungen
- DOM-Updates
- Speichern und Lesen von Local Storage und IndexedDB
Dabei stottert die Benutzerschnittstelle (z.B. beim Scrollen) und langsame Geräte zeigen u.U. Seite antwortet nicht oder Script unresponsive. Es gibt kein fork wie z.B. in C. So bleibt Javascript einfach und Datenstrukturen müssen nicht thread safe sein.
Web Worker – parallele Verarbeitung
Web Worker (und auch die verwandten Service Worker) laufen nicht im Haupt-Thread. Web Worker sind ein Kompromiss – sie laufen parallel zum Haupt-Thread, aber sie dürfen nicht auf das DOM zugreifen. Web Worker müssen für Zugriffe auf das DOM Nachrichten an den Haupt-Thread senden.
Wenn ein Worker Änderungen am DOM wünscht, muss er eine Nachricht an den Haupt-Thread senden.
Web Worker-Demo: Primzahlen bis n
Das Beispiel für ein Web Worker-Script sucht nach allen Primzahlen bis zur eingegebenen Zahl.
⏳ Noch nichts gestartet.
const worker = new Worker("js/prime-worker.js"); const input = document.getElementById("limitInput"); const button = document.getElementById("startButton"); const status = document.getElementById("status"); const result = document.getElementById("result"); button.onclick = () => { const n = parseInt(input.value); if (isNaN(n) || n < 2) { status.textContent = "❌ Bitte eine gültige Zahl größer als 1 eingeben."; result.textContent = ""; return; } status.textContent = `🔍 Suche Primzahlen bis ${n}...`; result.textContent = ""; worker.postMessage(n); }; worker.onmessage = (e) => { const { primes, limit } = e.data; status.textContent = `✅ ${primes.length} Primzahlen bis ${limit} gefunden.`; result.textContent = primes.join(", "); };
Das Web Worker-Script
Ein Web Worker braucht eine Javascript-Datei auf dem Server, das die Arbeiten im Hintergrund durchführt. Der Web Worker läuft also nicht im Browserfenster – ein Zugriff auf window wird demnach einen Fehler liefern. In einem Web Worker gibt es nur self. Web Worker haben keinen Zugriff auf das DOM – das kann gar nicht oft genug gesagt werden: kein getElementById(), kein window.onload …
setTimeout(), setInterval() und XMLHttpRequest() funktionieren aber auch in Web Workern.
Es gibt kein Limit für die Anzahl der Web Worker, aber Web Worker stellen eine nicht unbeträchtliche Last dar und dürften nicht beliebig einsetzbar sein.
Die URL des Web Worker-Scripts wird der HTML-Seite mit einem neu erzeugten Web Worker-Objekt übergeben:
const theWorker = new Worker ("web-worker.js");
// prime-worker.js function isPrime(n) { if (n < 2) return false; if (n === 2) return true; if (n % 2 === 0) return false; const sqrt = Math.sqrt(n); for (let i = 3; i <= sqrt; i += 2) { if (n % i === 0) return false; } return true; } self.onmessage = function (e) { const limit = e.data; const primes = [2]; for (let i = 3; i <= limit; i += 2) { if (isPrime(i)) { primes.push(i); } } console.log("Sende Ergebnis:", { limit, primes }); self.postMessage({ limit, primes }); };
Web Worker Events
Web Worker haben zwei Events:
- message schickt Daten vom Hintergrund-Thread zurück,
- das error-Event des Web Workers gibt einen evtl. Fehler zurück.
Der Haupt-Thread lauscht also auf Nachrichten vom Web Worker, aber zunächst schickt der Haupt-Thread eine Nachricht an den Web Worker.
WebWorker-Einsatz
Komplexe Berechnungen im Hintergrund sowie Lesen und Schreiben von localStorage und IndexedDB werden häufig als Beispiel für den Einsatz von Web Workern herangezogen. Web Worker können ein Backup des Dokuments im Hintergrund durchführen, 3D-Grafiken permanent rendern, während der Benutzer das 3D-Objekt im 3D-Workspace verschiebt.
Service Worker
Service Worker sind ein Proxy zwischen dem Browser und dem Netzwerk oder dem Cache. Sie werden im zentralen Javascript-File registriert, liegen genauso wie Web Worker in einer gesonderten Javascript-Datei und kümmern sich z.B. um Progressive Web Apps.
Sobald ein Service Worker installiert und aktiviert ist, übernehmen sie die Netzwerk-Anfragen des Dokuments und ziehen den lokalen Speicher heran, wenn der Benutzer nicht online ist.