Signatur
Beschreibung
Der Konstruktor new Worker() startet einen dedizierten Worker: einen eigenen Thread mit eigenem globalen Kontext (DedicatedWorkerGlobalScope), in dem das angegebene Skript läuft. So lassen sich rechenintensive Aufgaben wie Bildverarbeitung, das Parsen großer JSON-Daten, Kryptografie oder Kompression ausführen, ohne den Haupt-Thread und damit die Oberfläche zu blockieren.
Haupt-Thread und Worker teilen sich keinen Speicher. Sie tauschen Nachrichten über postMessage() und das message-Event aus. Die Daten werden dabei mit dem Structured-Clone-Algorithmus kopiert. Große Puffer wie ArrayBuffer lassen sich über die Transfer-Liste ohne Kopie übergeben. Im Worker gibt es kein DOM und kein window. Verfügbar sind aber zum Beispiel fetch, IndexedDB, WebSocket, OffscreenCanvas und Timer.
Mit der Option type: "module" wird das Skript als ES-Modul geladen. Dann funktionieren import/export, aber importScripts() nicht mehr. Klassische Worker laden weitere Skripte synchron über importScripts(). Die URL wird relativ zur Basis-URL des aufrufenden Dokuments aufgelöst. Sie muss denselben Ursprung haben, alternativ ist eine blob:- oder data:-URL möglich.
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $url Pflicht | string | URL | URL des Skripts, das der Worker ausführen soll. Die URL muss denselben Ursprung haben wie das Dokument. Möglich sind auch blob:-URLs und, mit Einschränkungen, data:-URLs. |
|
| $options | object | {} | Optionales Konfigurationsobjekt mit den unten aufgeführten Feldern. |
| $options.type | "classic" | "module" | "classic" | "module" lädt das Skript als ES-Modul mit import/export und Strict Mode. |
| $options.credentials | "omit" | "same-origin" | "include" | "same-origin" | Legt fest, ob Cookies und andere Zugangsdaten beim Laden mitgeschickt werden. Die Option ist nur für Modul-Worker relevant. |
| $options.name | string | "" | Frei wählbarer Name. Im Worker steht er als self.name zur Verfügung und erleichtert das Debuggen in den DevTools. |
Rückgabewert
Worker-Objekt. Über dieses Objekt sendet man mit postMessage() Nachrichten, beendet den Worker mit terminate() und empfängt die Events message, messageerror und error.Beispiele
Rechenintensive Aufgabe auslagern (klassischer Worker)
// main.js
const worker = new Worker('fib-worker.js', { name: 'fibonacci' });
worker.addEventListener('message', (event) => {
console.log('Ergebnis:', event.data);
worker.terminate(); // Thread freigeben
});
worker.addEventListener('error', (event) => {
console.error('Fehler im Worker:', event.message);
});
worker.postMessage(40);
// fib-worker.js
const fib = (n) => (n < 2 ? n : fib(n - 1) + fib(n - 2));
self.addEventListener('message', (event) => {
self.postMessage(fib(event.data));
});
Modul-Worker mit import und Promise-Wrapper
// main.js
const worker = new Worker(new URL('./parser.worker.js', import.meta.url), {
type: 'module'
});
const runInWorker = (payload) =>
new Promise((resolve, reject) => {
worker.onmessage = (e) => resolve(e.data);
worker.onerror = (e) => reject(new Error(e.message));
worker.postMessage(payload);
});
const result = await runInWorker('{"items":[1,2,3]}');
console.log(result.items.length);
// parser.worker.js
import { sum } from './math.js';
self.onmessage = ({ data }) => {
const parsed = JSON.parse(data);
self.postMessage({ ...parsed, total: sum(parsed.items) });
};
Inline-Worker über Blob-URL und Transfer eines ArrayBuffers
const code = `
self.onmessage = ({ data }) => {
const view = new Uint8Array(data);
for (let i = 0; i < view.length; i++) view[i] = 255 - view[i];
self.postMessage(data, [data]); // zurück transferieren
};
`;
const blobUrl = URL.createObjectURL(new Blob([code], { type: 'text/javascript' }));
const worker = new Worker(blobUrl);
const buffer = new Uint8Array([0, 100, 200]).buffer;
worker.onmessage = ({ data }) => {
console.log(Array.from(new Uint8Array(data)));
worker.terminate();
URL.revokeObjectURL(blobUrl);
};
worker.postMessage(buffer, [buffer]);
console.log(buffer.byteLength); // nach Transfer im Haupt-Thread leer
// Wichtig · Fallstricke
- Same-Origin-Pflicht: Skripte von einem anderen Ursprung, etwa von einem CDN, lösen einen
SecurityErroraus. Als Umweg lädt man den Code perfetchund startet ihn über eineblob:-URL oder im Worker perimportScripts(). - Ungültige URL: Eine URL, die sich nicht auflösen lässt, führt sofort zu einem
SyntaxError. Ladefehler wie ein 404 oder ein falscher MIME-Typ kommen dagegen asynchron alserror-Event beim Worker an. - Kein DOM: Im Worker gibt es weder
documentnochwindow,alertoderlocalStorage. Für DOM-Änderungen schickt man eine Nachricht an den Haupt-Thread. - Kosten: Jeder Worker ist ein echter Thread mit eigenem Speicher und eigener Startzeit. Man sollte Worker wiederverwenden oder einen Pool nutzen, statt pro Aufgabe einen neuen zu erzeugen, und nicht mehr benötigte Worker mit
terminate()beenden. - Kopierkosten:
postMessagekopiert die Daten. Bei großen Binärdaten die Transfer-Liste verwenden. Funktionen, DOM-Knoten und Klasseninstanzen samt Prototyp lassen sich nicht übertragen und lösen einenDataCloneErroraus. - CSP: Welche Worker-Quellen erlaubt sind, regelt die Direktive
worker-src(ersatzweisescript-src). Für Blob-Worker mussblob:dort ausdrücklich erlaubt sein. - Kompatibilität: Klassische Worker werden überall unterstützt.
type: "module"kann Firefox erst ab Version 114. Bundler wie Vite oder webpack erkennen das Musternew Worker(new URL(..., import.meta.url)). In Node.js gibt es stattdessenworker_threadsmit einer anderen API.