Start · Sprachen · JavaScript · Referenz · SharedWorkerGlobalScope

SharedWorkerGlobalScope

Schnittstelle

Der globale Ausführungskontext eines <code>SharedWorker</code>, im Worker-Skript über <code>self</code> erreichbar; empfängt Verbindungen mehrerer Seiten über das <code>connect</code>-Event.

seit JavaScript Baseline 2024 (Chrome 4+, Firefox 29+, Safari 16+; Kategorie: webapi

Signatur

interface SharedWorkerGlobalScope extends WorkerGlobalScope

Beschreibung

SharedWorkerGlobalScope ist das globale Objekt in einem Skript, das per new SharedWorker(url) gestartet wurde. Im Worker verweist self (bzw. globalThis) auf diese Instanz. Die Schnittstelle erbt von WorkerGlobalScope, deshalb stehen dort auch fetch(), importScripts(), setTimeout(), indexedDB, location und navigator zur Verfügung. Auf das DOM, window und document hast du keinen Zugriff.

Anders als bei einem dedizierten Worker teilen sich alle Browsing-Kontexte desselben Ursprungs (Tabs, iframes, Fenster), die dieselbe Skript-URL und denselben name verwenden, eine einzige Worker-Instanz. Jede neue Verbindung löst im Worker das Event connect aus. Dessen Eigenschaft event.ports[0] enthält einen MessagePort, über den der Worker mit genau dieser Seite kommuniziert. Ein globales postMessage() gibt es deshalb hier nicht.

Typische Einsatzfälle sind eine gemeinsame WebSocket-Verbindung für alle Tabs, zentrales Caching, die Abstimmung zwischen Tabs (z. B. Abmeldung in allen Tabs) und gemeinsam genutzter Zustand.

Wichtige Mitglieder:

  • name (nur lesbar): der Name, der beim Konstruktor über new SharedWorker(url, { name }) übergeben wurde.
  • close(): beendet den Worker sofort, also für alle verbundenen Seiten.
  • onconnect / Event connect: wird bei jeder neuen Verbindung ausgelöst.

Rückgabewert

Typ
SharedWorkerGlobalScope
Beschreibung
Im Worker-Skript liefert self bzw. globalThis die Instanz dieser Schnittstelle. Sie kann nicht direkt erzeugt werden.

Beispiele

Grundgerüst: Verbindungen annehmen und antworten

// shared.js (Worker-Skript)
self.addEventListener('connect', (event) => {
  const port = event.ports[0];
  port.addEventListener('message', (e) => {
    port.postMessage(`Echo von ${self.name}: ${e.data}`);
  });
  port.start(); // nötig bei addEventListener (bei onmessage automatisch)
});

// main.js (Seite)
const worker = new SharedWorker('shared.js', { name: 'echo' });
worker.port.onmessage = (e) => console.log(e.data);
worker.port.postMessage('Hallo');
Echo von echo: Hallo

Nachrichten an alle offenen Tabs verteilen

// broadcast-worker.js
const ports = new Set();

self.onconnect = ({ ports: [port] }) => {
  ports.add(port);
  port.onmessage = ({ data }) => {
    if (data.type === 'bye') {
      ports.delete(port); // Tab meldet sich beim Schließen ab
      return;
    }
    for (const p of ports) p.postMessage(data);
  };
};

// in jedem Tab
const w = new SharedWorker('broadcast-worker.js');
w.port.onmessage = ({ data }) => console.log('Empfangen:', data);
w.port.postMessage({ type: 'logout' });
window.addEventListener('pagehide', () => w.port.postMessage({ type: 'bye' }));
Empfangen: { type: 'logout' } // in allen Tabs

Gemeinsamer Zähler und Worker beenden

// counter-worker.js
let count = 0;

self.onconnect = (event) => {
  const port = event.ports[0];
  count++;
  port.postMessage({ connections: count, isShared: self instanceof SharedWorkerGlobalScope });
  port.onmessage = ({ data }) => {
    if (data === 'shutdown') self.close(); // beendet den Worker für alle Seiten
  };
};

// main.js
const cw = new SharedWorker('counter-worker.js');
cw.port.onmessage = ({ data }) => console.log(data);
{ connections: 1, isShared: true } // im zweiten Tab: connections: 2

// Wichtig · Fallstricke

  • Kompatibilität: In aktuellen Desktop-Browsern und seit Safari 16 verfügbar. In Chrome für Android und Samsung Internet gibt es keine Unterstützung. Prüfe die Verfügbarkeit mit 'SharedWorker' in window und sieh eine Ausweichlösung vor, z. B. BroadcastChannel oder einen dedizierten Worker.
  • Rufst du port.addEventListener('message', …) auf, musst du anschließend port.start() aufrufen. Beim Setzen von onmessage startet der Port automatisch.
  • Das Schließen eines Tabs löst kein zuverlässiges Event aus, das der Worker empfangen kann. Die Tabs sollten sich daher selbst abmelden, z. B. bei pagehide. Sonst sammeln sich tote Ports an und es entsteht ein Speicherleck.
  • Die Instanz wird nur geteilt, wenn Ursprung, Skript-URL und name übereinstimmen. Private und normale Fenster bekommen jeweils eigene Instanzen.
  • self.close() beendet den Worker für alle verbundenen Seiten.
  • Fehlermeldungen mit console.log aus dem Worker erscheinen meist nicht in der Konsole der Seite. In Chrome findest du sie unter chrome://inspect/#workers.
  • Der Worker gehorcht der Same-Origin-Policy und der CSP-Direktive worker-src. Prüfe Nachrichten von Ports, bevor du sie weiterverarbeitest.