Lesson 0005 · ~12 minutes

Shared workers: one process, many tabs

One skill: decide when multi-context work needs a SharedWorker versus a dedicated worker, BroadcastChannel, or a service worker.

Win for this lesson

You can defend “shared worker yes / no” when the product story is multi-tab coordination — without treating every tab problem as a worker problem.

1. What problem does SharedWorker solve?

A SharedWorker is a worker that multiple browsing contexts (tabs, windows, iframes) of the same origin can connect to. MDN: once created, any same-origin script can obtain a reference and talk to it; it stays alive while something holds a reference.

Dedicated worker mental model: one owner page, offload my CPU. Shared worker mental model: one long-lived coordinator process that several UIs attach to.

Still not magic threads

Same isolation rules: no DOM, message-passing (clone/transfer), capability list from lesson 4. You gain a shared JS realm across tabs — not free shared DOM or free shared React state.

2. API shape (port, not worker.onmessage)

From MDN Using Web Workers: communication is via an explicit MessagePort on worker.port. Inside the worker, clients arrive on connect.

// each tab
const sw = new SharedWorker("shared.js");
sw.port.onmessage = (e) => console.log("from hub", e.data);
sw.port.postMessage({ type: "join", tabId: crypto.randomUUID() });

// shared.js
const ports = new Set();

onconnect = (e) => {
  const port = e.ports[0];
  ports.add(port);

  port.onmessage = (ev) => {
    // example: fan-out to every connected tab
    for (const p of ports) {
      p.postMessage({ type: "broadcast", payload: ev.data });
    }
  };
};

3. Decision map: multi-tab tools

Dedicated Worker

One page needs CPU offload. No shared process across tabs (each tab can spawn its own).

BroadcastChannel

Same-origin tabs need pub/sub messages only — no shared memory, no single coordinator process. Lightest option for “tell other tabs X happened.”

SharedWorker

You need one in-memory coordinator: single WebSocket to a server, shared cache of derived state, election of a leader tab’s work, multi-window map editor (spec multiviewer pattern).

Service Worker

Network proxy, offline, push — different lifecycle and job (lesson 1/4).

Default rule

If tabs only need to notify each other, start with BroadcastChannel (or storage events as a last resort). If they need a shared process that holds state or owns a scarce resource (one socket, one heavy engine), design a SharedWorker. If only one tab exists and the issue is jank, dedicated worker.

4. Design-review deal-breakers

Risk Why it bites
Cross-origin tabs SharedWorker requires exact same origin — not “same site” loosely.
Browser support / mobile quirks Historically rockier than dedicated workers; verify target browsers (MDN compat). Have a fallback story.
No fan-out built-in You manage ports. Forgetting to track disconnects leaks or ghosts messages.
Debugging opacity Not the same DevTools surface as a page — use browser worker inspectors (chrome://inspect/#workers, etc.).
Overkill “Sync logout across tabs” rarely needs a shared process — BroadcastChannel + clear storage often enough.

5. Practice — pick the multi-tab tool

Equal-length options. Product design reviews.

Scenario A

Trading dashboard: up to 8 tabs open; product wants one WebSocket to the market feed, all tabs update.

Scenario B

When the user logs out in one tab, other same-origin tabs should clear session UI within a second.

Scenario C

Photo editor: one tab, multi-second image filter freezes the UI. No multi-window requirement.

Scenario D

App shell on app.example.com and widget iframe on cdn.example.com must share one in-memory session bus.

6. What to remember

Ask your teacher Leader-election patterns, WebSocket-in-SharedWorker designs, or whether your multi-tab bug needs a shared process — ask in chat.

Primary source (read next)

MDN — SharedWorker plus the shared-worker section of Using Web Workers. Optional contrast: BroadcastChannel.