Start · Sprachen · JavaScript · Referenz · new SharedWorker()

new SharedWorker()

Methode

Erstellt ein <code>SharedWorker</code>-Objekt, das das Skript an der angegebenen URL in einem Worker ausführt, den sich mehrere Fenster, Tabs oder iframes desselben Ursprungs teilen.

seit JavaScript Chrome 4+, Firefox 29+, Safari 16+, Chrome Android Kategorie: webapi

Signatur

new SharedWorker(url, options)

Beschreibung

Der Konstruktor SharedWorker() startet einen geteilten Worker, also einen Hintergrund-Thread, auf den mehrere Browsing-Kontexte (Tabs, Fenster, iframes, auch andere Worker) mit demselben Ursprung zugreifen. Existiert schon ein SharedWorker mit gleicher Skript-URL und gleichem name, legt der Browser keinen neuen Worker an. Stattdessen verbindet er den Aufrufer mit der laufenden Instanz.

Die Kommunikation läuft immer über einen MessagePort, den du als worker.port erreichst. Im Worker-Skript meldet das Ereignis connect jede neue Verbindung. Den zugehörigen Port findest du in event.ports[0]. Typische Einsatzfälle sind eine einzige WebSocket-Verbindung für alle Tabs, ein gemeinsamer Zwischenspeicher, Status-Synchronisierung zwischen Tabs oder das Bündeln teurer Berechnungen.

Der Worker bleibt aktiv, solange noch mindestens ein verbundener Kontext existiert. Wird der letzte Tab geschlossen, beendet der Browser den Worker. Mit der Option type: "module" kannst du ES-Module samt import im Worker verwenden.

Parameter

Name Typ Default Beschreibung
$url Pflicht string | URL URL des Worker-Skripts. Das Skript muss dem Same-Origin-Prinzip genügen. Relative URLs werden relativ zur Basis-URL des Dokuments aufgelöst.
$options string | { name?: string, type?: "classic" | "module", credentials?: "omit" | "same-origin" | "include" } { type: "classic", credentials: "same-origin" } Als Zeichenkette ist das der Name des Workers (ältere Kurzform). Als Objekt:
  • name: bestimmt zusammen mit der URL, welche Instanz geteilt wird. Im Worker steht er als self.name zur Verfügung.
  • type: "classic" oder "module".
  • credentials: legt fest, ob beim Laden eines Modul-Workers Anmeldedaten mitgeschickt werden.

Rückgabewert

Typ
SharedWorker
Beschreibung
Ein SharedWorker-Objekt. Die Eigenschaft port (MessagePort) dient zur Kommunikation. Das Ereignis error wird ausgelöst, wenn das Skript nicht geladen werden kann.

Beispiele

Einfacher geteilter Zähler über mehrere Tabs

// main.js – in jedem Tab eingebunden
const worker = new SharedWorker('/counter-worker.js');

worker.port.onmessage = (event) => {
  console.log(`Verbundene Tabs: ${event.data}`);
};

// onmessage startet den Port implizit; bei addEventListener wäre port.start() nötig
worker.port.postMessage('hallo');

// counter-worker.js
const ports = [];

self.addEventListener('connect', (event) => {
  const port = event.ports[0];
  ports.push(port);
  port.onmessage = () => {
    // allen verbundenen Tabs die aktuelle Anzahl mitteilen
    ports.forEach((p) => p.postMessage(ports.length));
  };
});
Verbundene Tabs: 1 // nach Öffnen eines zweiten Tabs in beiden: Verbundene Tabs: 2

Modul-Worker mit Namen und Fehlerbehandlung

if ('SharedWorker' in window) {
  const worker = new SharedWorker(new URL('./sync-worker.js', import.meta.url), {
    type: 'module',
    name: 'app-sync'
  });

  worker.addEventListener('error', (e) => {
    console.error('SharedWorker konnte nicht geladen werden:', e.message);
  });

  worker.port.addEventListener('message', ({ data }) => {
    console.log('Status:', data);
  });
  worker.port.start(); // Pflicht bei addEventListener

  worker.port.postMessage({ type: 'subscribe', topic: 'news' });
} else {
  console.warn('SharedWorker nicht unterstützt – Fallback auf BroadcastChannel');
}
Status: { subscribed: 'news' }

Eine WebSocket-Verbindung für alle Tabs

// ws-worker.js
const ports = new Set();
const socket = new WebSocket('wss://example.com/live');

socket.addEventListener('message', (e) => {
  // eingehende Nachricht an alle Tabs weiterreichen
  for (const port of ports) port.postMessage(e.data);
});

self.onconnect = ({ ports: [port] }) => {
  ports.add(port);
  port.onmessage = ({ data }) => {
    if (data === 'close') ports.delete(port);
    else if (socket.readyState === WebSocket.OPEN) socket.send(data);
  };
};

// main.js
const ws = new SharedWorker('/ws-worker.js', 'live-socket');
ws.port.onmessage = ({ data }) => console.log('Live:', data);
window.addEventListener('pagehide', () => ws.port.postMessage('close'));
Live: {"event":"update","id":42}

// Wichtig · Fallstricke

  • Browser-Unterstützung: SharedWorker funktioniert in Desktop-Chrome, Edge, Firefox und Safari 16+. Auf Android fehlte die Unterstützung lange. Chrome für Android hat sie erst mit Version 142 bekommen, Samsung Internet unterstützt SharedWorker nicht. Frag die Unterstützung also immer mit 'SharedWorker' in window ab und nutze bei Bedarf BroadcastChannel als Ersatz.
  • Same-Origin: Die Skript-URL muss denselben Ursprung wie das Dokument haben, sonst wirft der Konstruktor einen SecurityError. Eine ungültige URL führt zu einem SyntaxError. Private Fenster und unterschiedliche Speicher-Partitionen (z. B. Third-Party-iframes) teilen sich keine Instanz.
  • Identität: Welche Instanz geteilt wird, hängt von URL und name ab. Hat eine bestehende Instanz einen anderen type oder andere credentials, löst das einen Fehler aus.
  • Port starten: Setzt du nur port.onmessage, wird der Port automatisch gestartet. Mit addEventListener('message', …) musst du port.start() selbst aufrufen, sonst kommen keine Nachrichten an.
  • Verbindungen aufräumen: Es gibt kein zuverlässiges Ereignis, wenn ein Tab geschlossen wird. Getrennte Ports solltest du selbst verwalten, etwa mit einer Abmelde-Nachricht bei pagehide oder mit Heartbeats.
  • Fehlersuche: Die Konsole des Workers findest du in Chrome unter chrome://inspect/#workers, in Firefox unter about:debugging.
  • Im Worker gibt es kein DOM. Verfügbar sind unter anderem fetch, IndexedDB und WebSocket.