JavaScript is famously single-threaded. When your web application runs a complex mathematical operation, compresses a 50-megapixel photo, or extracts an audio waveform, that computation runs on the exact same thread responsible for rendering HTML, painting CSS animations, and responding to user clicks. The result is the dreaded browser freeze: stuttering scrolling, unresponsive buttons, and failed interactions.
To build desktop-class web applications like Crate, offloading heavy computations to Web Workers is mandatory. Here is how modern web developers harness hardware multi-core CPUs in the browser.
The Main Thread vs. Background Workers
A standard browser tab allocates one primary thread for the DOM and user interface. If a task occupies this thread for more than 16 milliseconds (on 60Hz displays) or 8 milliseconds (on 120Hz displays), a frame is dropped (known as jank).
A Dedicated Web Worker spawns a completely separate OS-level thread. While it cannot touch the DOM (`document` or `window` are undefined), it possesses full access to timers, `fetch`, WebSockets, IndexedDB, and WebAssembly execution runtimes.
The Zero-Copy Breakthrough: Transferable Objects
Historically, passing data between the main thread and a Web Worker used the structured clone algorithm. If you passed a 200MB uncompressed raw video buffer to a worker, the browser duplicated that 200MB in memory, causing a momentary micro-stutter.
Transferable Objects eliminate cloning completely. By transferring ownership of an `ArrayBuffer`, the memory is moved instantaneously (in zero milliseconds) from the main thread to the worker context without memory duplication:
OffscreenCanvas: Hardware-Accelerated Worker Rendering
Traditionally, graphics rendering had to occur on the main thread because canvas elements live in the DOM. With `OffscreenCanvas`, you can transfer control of an HTML <canvas> directly into a Web Worker:
In game engines like TypeCrate or real-time video filters, the Web Worker renders 2D/WebGL graphics continuously without ever blocking typing inputs, keyboard events, or modal dialogues on the main page.
SharedArrayBuffer & Atomics: Shared Memory Multiprocessing
For ultra-high performance applications (such as multi-threaded FFmpeg WASM builds), multiple workers can read and write to the exact same memory address concurrently using `SharedArrayBuffer`. To prevent race conditions, the `Atomics` API provides atomic read, write, and wait/notify primitives matching native C++ threading models.
Summary: When to Spawn a Worker
- Always use Workers: Video/audio transcoding, image resizing/quantization, cryptographic hashing, heavy text parsing, AI model inference.
- Keep on Main Thread: Quick DOM updates, standard form validation, micro-animations handled via CSS transforms.
