Signatur
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 übernew SharedWorker(url, { name })übergeben wurde.close(): beendet den Worker sofort, also für alle verbundenen Seiten.onconnect/ Eventconnect: wird bei jeder neuen Verbindung ausgelöst.
Rückgabewert
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');
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' }));
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);
// 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 windowund sieh eine Ausweichlösung vor, z. B.BroadcastChanneloder einen dedizierten Worker. - Rufst du
port.addEventListener('message', …)auf, musst du anschließendport.start()aufrufen. Beim Setzen vononmessagestartet 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.logaus dem Worker erscheinen meist nicht in der Konsole der Seite. In Chrome findest du sie unterchrome://inspect/#workers. - Der Worker gehorcht der Same-Origin-Policy und der CSP-Direktive
worker-src. Prüfe Nachrichten von Ports, bevor du sie weiterverarbeitest.