Lesson 0006 · ~12 minutes · synthesis
One skill: given a feature brief, write a complete concurrency choice — tool, message design, lifecycle, and one risk you own.
This is the durable skill from MISSION.md: defend an off-main-thread choice in a design review without hand-waving.
Run in order. Earlier gates reject more options than later ones.
Is main-thread jank from pure work the issue? Or DOM/layout? Or offline? Measure; don’t worker a paint problem. (Lessons 1, 4)
Dedicated = one page CPU. BroadcastChannel = tab notify. SharedWorker = one same-origin coordinator. Service worker = network/offline. (Lessons 1, 5)
Clone by default; transfer big binaries; patches/chunks for huge high-frequency state. No functions/DOM on the wire. (Lesson 3)
“We use main | dedicated | shared | BroadcastChannel | SW because problem class; messages are clone | transfer | patches; we own lifecycle + bundler + one risk.”
Keep the print playbook open after this course — compressed form of all six lessons.
Pick the best default package. Equal-length options.
One-tab dashboard. User drops a 50 MB CSV; parse freezes UI 3s. Render a table from summary rows. SPA route can unmount.
User logs out in tab A; tabs B and C on the same origin must clear session UI quickly. No shared compute engine.
Same-origin app; users open many tabs. Product wants one WebSocket to the server; all tabs show the feed.
Document model (~2 MB) lives in a worker. Team posts the entire document to main on every keystroke for render.
Proposal: move React list virtualization (measure nodes, write transforms) entirely into a dedicated worker.
Product goal: cache app shell and work offline after first visit. No heavy client-side compute story.
Without scrolling up — answer mentally, then expand.
postMessage(u8, [u8.buffer]), what is
u8.byteLength on the sender?
0 — the buffer was transferred (detached). Ownership moved.
terminate() vs close()?
Main thread: worker.terminate() (hard kill). Inside
worker: close() (self-shutdown / discard queue).
When tabs only need to notify each other — no shared process, single socket, or shared in-memory engine required.
Re-skim web.dev — Off the main thread and the WHATWG workers intro as the architecture spine. Your print companion is decision-playbook.html.