awesome-everything RU
↑ Back to the climb

Browser & Frontend Runtime

Workers: code and snippet reading

Crux Read real worker, postMessage, and service-worker snippets — predict the runtime behaviour or the bug, then pick the highest-leverage fix a senior engineer makes first.
Your altitude — climbing toward senior
ZeroJuniorMiddleSenior
You are at senior altitude — in orbit
◷ 14 min

Worker bugs hide in the message boundary and the lifecycle handler, not in the algorithm. Read each snippet, predict what actually happens at the boundary, and choose the fix before reaching for a profiler.

Goal

Practise the loop you run in every worker incident: read the postMessage call or the lifecycle handler, find the hidden clone tax or the detached-buffer or the missing waitUntil, and reach for the highest-leverage fix.

Snippet 1 — the clone that did not move

// main.js — offloading a heavy image filter to a worker
const worker = new Worker('filter.js', { type: 'module' });
const pixels = new Uint8ClampedArray(width * height * 4); // ~32 MB

worker.postMessage({ pixels, width, height });   // (A)
applyOtherUiWork();                                // (B) runs ~32 ms late
Quiz

Line (B) runs about 32 ms later than expected even though the filter runs in the worker. What is happening at line (A) and what is the one-line fix?

Snippet 2 — the buffer used after transfer

// main.js
const buf = new Float32Array(1_000_000);
fillSamples(buf);

worker.postMessage(buf, [buf.buffer]);   // transferred
const sum = buf.reduce((a, x) => a + x); // (C) reads buf again
Quiz

What happens at line (C), and what does it tell you about transfer semantics?

Snippet 3 — the install handler that loses its cache

// sw.js
self.addEventListener('install', () => {
  caches.open('shell-v3').then(cache =>
    cache.addAll(['/index.html', '/app.4f3a1c.js'])
  );
});
Quiz

Under load this service worker sometimes activates with an empty or half-populated cache. What is the defect and the fix?

Snippet 4 — the OffscreenCanvas handoff

// main.js
const canvas = document.querySelector('#viz');
const offscreen = canvas.transferControlToOffscreen();
worker.postMessage({ offscreen }, [offscreen]);

// later, on the main thread:
const ctx = canvas.getContext('2d');   // (D)
ctx.fillRect(0, 0, 100, 100);          // (E)
Quiz

The worker renders fine, but lines (D)–(E) on the main thread misbehave. What happens and why?

Recap

Every worker incident is read at the boundary, not in the algorithm: a by-value postMessage of a large buffer blocks the sender on a synchronous structured clone, so transfer the ArrayBuffer; a transferred buffer is detached on the sender, so never read it afterward (use SharedArrayBuffer if you must share); a service-worker install must wrap async cache population in event.waitUntil or the worker advances or dies early; and transferControlToOffscreen makes canvas ownership exclusive, so the main thread can no longer draw. Read the message and lifecycle handlers first — that is where the cost and the bugs live.

Continue the climb ↑Workers: build a responsive offload pipeline
shortcuts expand
search
K
prev piece
k
next piece
j
cycle tier
t
this menu
?
sources3
expand
  1. 01
  2. 02
  3. 03

Trademarks belong to their respective owners. Editorial reference only.