Suggest an editImprove this articleRefine the answer for “Web Workers in JavaScript”. Your changes go to moderation before they’re published.Approval requiredContentWhat you’re changing🇺🇸EN🇺🇦UAPreviewTitle (EN)Short answer (EN)**A Web Worker is a separate JavaScript execution thread that runs in parallel with the main thread (the UI thread), so it never blocks the interface.** The main thread creates it with `new Worker('worker.js')`, and from then on both sides talk only through messages: `postMessage` sends data, `onmessage` receives it. The transfer is asynchronous and the data is copied by the structured clone algorithm rather than shared by reference. A worker cannot see the DOM, `window`, `document`, `alert()` or `localStorage`, but it does have `fetch`, `XMLHttpRequest`, `WebSocket`, `setTimeout`, `indexedDB` and `crypto`. There are three types: Dedicated Worker (one to one), Shared Worker (shared across tabs) and Service Worker (a proxy between the page and the network). ```javascript const worker = new Worker('worker.js'); worker.postMessage(1e9); worker.onmessage = (event) => console.log('Result:', event.data); ``` **Key point:** heavy computation runs on a background thread, communication happens only through messages, and the worker has no DOM access.Shown above the full answer for quick recall.Answer (EN)Image**A Web Worker is a separate JavaScript execution thread that runs in parallel with the main thread (the UI thread).** It does not block the interface: heavy computation runs in the background, and the result comes back to the main thread as a message. ## Theory ### TL;DR - JavaScript in the browser is single threaded: rendering, event handling and your code all live on one thread. - A heavy synchronous loop occupies the Event Loop, and the page freezes. - A Web Worker moves the computation onto a separate thread, so the UI stays responsive. - The threads talk only through messages: `postMessage` and `onmessage`, with data serialised by the structured clone algorithm. - A worker has no access to `document`, `window`, `alert()` or `localStorage`, but it does have `fetch`, `XMLHttpRequest`, `WebSocket`, `setTimeout`, `indexedDB` and `crypto`. - There are three types: Dedicated Worker, Shared Worker, Service Worker. ### Quick example ```javascript // main.js const worker = new Worker('worker.js'); worker.postMessage(1e9); // send the task worker.onmessage = (event) => { console.log('Result:', event.data); }; ``` ```javascript // worker.js onmessage = (event) => { let sum = 0; for (let i = 0; i < event.data; i++) sum += i; postMessage(sum); // send the result back }; ``` Now the heavy calculation runs in the background while the UI stays responsive. ### The single threaded JavaScript problem JavaScript in the browser is single threaded, so one thread does everything at once: - rendering the page - handling events - running your code If you start a heavy loop on that thread: ```javascript for (let i = 0; i < 1e9; i++) {} console.log('Done!'); ``` the page freezes: the interface stops responding until the loop finishes, because the Event Loop is busy. ### How it works under the hood 1. The main thread creates a worker with `new Worker('script.js')`. 2. The browser starts a separate JS thread. 3. The threads communicate through messages (message passing). 4. The transfer is asynchronous and the data is serialised (structured clone). 5. The worker has no access to the DOM, `window` or `document`. #### Message passing Communication goes through the `postMessage` and `onmessage` events: ```javascript // main.js worker.postMessage({ action: 'sum', a: 5, b: 7 }); // worker.js onmessage = (e) => { if (e.data.action === 'sum') { postMessage(e.data.a + e.data.b); } }; ``` You can send: - strings, numbers, objects - `ArrayBuffer`, `Blob`, `File`, `ImageBitmap` - even Transferable objects, to hand over data without copying it ### Limits and the available API A Web Worker is isolated: - no access to `document`, `window`, `alert()`, `localStorage` - access to `fetch`, `XMLHttpRequest`, `WebSocket`, `setTimeout`, `indexedDB`, `crypto` and the like #### Stream processing inside a worker A worker can use Streams and the Fetch API: ```javascript onmessage = async (e) => { const response = await fetch(e.data.url); const text = await response.text(); postMessage(text.length); }; ``` That way network data is processed in the background without blocking the UI at all. ### Types of Web Workers | Type | Where it is used | Characteristics | | --- | --- | --- | | **Dedicated Worker** | One to one | Works only with the script that created it | | **Shared Worker** | Several tabs or scripts | One worker for all pages (per origin + URL) | | **Service Worker** | Between the browser and the network | Caches requests, works even offline | #### Shared Worker example ```javascript // shared-worker.js onconnect = (event) => { const port = event.ports[0]; port.onmessage = (e) => { port.postMessage(`Received: ${e.data}`); }; }; ``` Several tabs can connect to a single Shared Worker, for example to exchange data between tabs. #### Service Worker as a special type > A Service Worker is not just a thread, it is a proxy between the browser and the network. It intercepts HTTP requests, caches responses and makes offline work possible. Examples: PWA applications, push notifications, background sync. ```javascript // service-worker.js self.addEventListener('fetch', (event) => { event.respondWith( caches.match(event.request).then((cached) => { return cached || fetch(event.request); }) ); }); ``` This means: if a cached response exists, serve it, otherwise load it from the network. #### An example of "parallel" computation ```javascript const workers = Array.from({ length: 4 }, () => new Worker('calc.js')); let completed = 0; let result = 0; workers.forEach((w, i) => { w.postMessage(i); w.onmessage = (e) => { result += e.data; if (++completed === 4) console.log('Done:', result); }; }); ``` This spreads the computation across several threads, a kind of pseudo parallelism. ### When Web Workers are worth it | Scenario | Why it helps | | --- | --- | | Complex computation | JSON parsing, cryptography, machine learning | | Large data processing | filtering and aggregating arrays, handling CSV | | Image work | compression, filters, thumbnail generation | | Games and animation | physics calculations without interface lag | | WebSocket plus data analysis | stream processing | A simple analogy: > Imagine the browser is a kitchen. The main thread (the main JS) is the chef who cooks the dish and serves the guests. The Web Worker is an assistant in another kitchen who chops the vegetables. The chef hands over a task, the assistant does it in the background and returns the result. Neither one gets in the other's way. Summary: | Component | What it does | | --- | --- | | **Web Worker** | A separate thread for running code | | **Main advantage** | Does not block the UI | | **Data exchange** | Through `postMessage` / `onmessage` | | **Limits** | No access to the DOM, `window`, `document` | | **Types** | Dedicated, Shared, Service Worker | | **Main uses** | Background computation, caching, offline mode, sync | ### Common mistakes - Reaching for `document` or `window` inside a worker. They are not there, so the data you need has to arrive as a message. - Expecting an object to be passed by reference. Data is copied by structured clone, so large arrays are better handed over as Transferable objects (`ArrayBuffer`), otherwise the copying itself becomes the bottleneck. - Sending functions, DOM nodes or class instances with methods through `postMessage`. Structured clone does not support them and throws. - Spawning a new worker for every small call. Starting a thread costs time and memory, so reuse workers or keep a pool of them. - Confusing a Web Worker with a Service Worker. The first is for computation, the second for intercepting network requests and offline mode. - Forgetting `worker.terminate()`. A worker stays alive until you stop it explicitly or the page is closed.For the reviewerNote to the moderator (optional)Visible only to the moderator. Helps review go faster.