HTML Web Workers
Previously, Drag and Drop moved or labeled DOM payloads with pointer events (draggable, dataTransfer, drop). This lesson leaves pointer gestures and introduces Web Workers: running JavaScript in a background thread so a long loop does not freeze buttons and scrolling. Your HTML page still loads a script; that script creates a Worker, sends work with postMessage, and paints results when a message arrives. Scope stays practical — create, message, no DOM in the worker — not SharedWorker fleets, OffscreenCanvas products, or a full concurrency engineering course.
Why web workers in an HTML course
Beginners hit a frozen page when a busy loop runs on the main thread. Workers are the common first browser API for “compute in the background.” After drag-and-drop’s “JS handles pointer drop,” this lesson’s split is different: the page script owns the DOM and UI; the worker owns heavy calculation and talks only through messages. You need new Worker(…), postMessage / onmessage, and the rule that workers cannot call document.querySelector — enough for intro pages without building a thread pool or a service-worker PWA.
Direct answer
1) Create a worker with new Worker("worker.js") (or a Blob URL in single-file demos).
2) Send input with worker.postMessage(data) from the page.
3) In the worker, listen for onmessage (or message), compute, then postMessage(result) back.
4) On the page, handle worker.onmessage and update the DOM there — never inside the worker.
5) Classic dedicated workers have no direct DOM, window, or document access.
6) Prefer http(s) hosting (or Blob demos). Odd file:// paths often fail to load worker scripts.
📊 main thread vs worker
| Topic | Main page script | Dedicated worker |
|---|---|---|
| Typical role | UI, DOM, create Worker | Heavy compute off UI thread |
| Talks via | postMessage / onmessage | postMessage / onmessage |
| Can touch DOM? | Yes | No — return data instead |
| Beginner entry | new Worker(url or Blob) | onmessage + compute + postMessage |
| This course depth | Required | Required (simple round-trip) |
| Not this lesson | Drag-and-drop gestures | SharedWorker / Service Worker products |
Tiny Blob Worker round-trip
This single HTML file builds a tiny worker from a Blob so you do not need a separate worker.js on disk. The page sends a number; the worker returns a simple sum loop result.
<button id="go" type="button">Run in worker</button>
<pre id="out"></pre>
<script>
const out = document.getElementById("out");
const src =
"onmessage=function(e){" +
"var n=e.data,s=0,i;" +
"for(i=1;i<=n;i++){s+=i;}" +
"postMessage(s);" +
"};";
const blob = new Blob([src], { type: "application/javascript" });
const w = new Worker(URL.createObjectURL(blob));
w.onmessage = function (e) {
out.textContent = "Sum 1..40 = " + e.data;
};
document.getElementById("go").onclick = function () {
out.textContent = "Working…";
w.postMessage(40);
};
</script>
Reading the round-trip calls
Blob+URL.createObjectURLbuilds a worker script URL without a second filenew Worker(url)starts a background script for this pagepostMessage(40)sends a number into the worker- Worker
onmessageruns the loop andpostMessages the sum back - Page
onmessagewrites into<pre>— DOM stays on the main thread - Unlike Drag and Drop, nothing uses
draggableordataTransfer— this is threads + messages - Keep demos tiny: one message in, one result out
UI stays on the main thread
Workers return data; the page script decides what the user sees. This demo asks the worker for a label string, then the button handler’s onmessage updates the paragraph — proving the worker never touches the DOM.
<button id="ask" type="button">Ask worker</button>
<p id="msg">Waiting…</p>
<script>
const msg = document.getElementById("msg");
const src =
"onmessage=function(e){" +
"postMessage('Worker got: ' + e.data);" +
"};";
const w = new Worker(
URL.createObjectURL(new Blob([src], { type: "application/javascript" }))
);
w.onmessage = function (e) {
msg.textContent = e.data;
};
document.getElementById("ask").onclick = function () {
w.postMessage("hello");
};
</script>
Reading the UI-ownership idea
- Worker only echoes a string — no
documentcalls - Page
onmessageassignsmsg.textContent - Same messaging bridge as the sum demo; different payload
- Still not Drag and Drop — no drop zones or pointer payloads
- Still not a Service Worker / offline PWA lesson
- Choose a worker when work is heavy enough to risk freezing UI
- Next optional lesson: SSE streams server events to the page — a different browser pattern
Choosing when to use a worker
- Long CPU loop that would freeze scrolling: good intro worker fit
- Tiny one-line string tweak: usually stay on the main thread
- Moving a card into a dashed zone: that was Drag and Drop, not workers
- Reading GPS coordinates: that was Geolocation, not workers
- SharedWorker hubs / Service Worker caching products: beyond this HTML intro
- Updating buttons from inside the worker: not allowed — message the page instead
Practice — create, message, paint
- Paste the Blob sum demo; click the button; confirm the sum appears.
- Change
40to another smalln; confirm the result changes. - Paste the echo demo; confirm the paragraph updates only after the worker replies.
- (Optional) Skim a real
worker.jsfile pattern: pagenew Worker("worker.js")when you serve over http(s). - Write one sentence: Drag and Drop moves/labels with pointer events; Web Workers compute off-thread via messages.
- Prefer http(s) or Blob demos over relying only on
file://if a Worker URL fails. - Peek ahead: SSE (Server-Sent Events) pushes updates from the server — not background CPU workers.
Easy mistakes
- Expecting
document.querySelectorto work inside a classic dedicated worker - Using a worker for tiny work that does not need a second thread
- Confusing Web Workers with Drag and Drop (messages ≠ pointer payloads)
- Loading
worker.jsfrom incompatible origins or fragilefile://paths - Forgetting to handle
onmessageon the page so results never appear - Treating Blob demos as the only production pattern (real apps often use a
.jsfile URL) - Treating this intro as a SharedWorker, Service Worker, or full concurrency certification course
Summary
- Web Workers run JavaScript off the main UI thread
- Talk with
postMessage/onmessage; paint the DOM only on the page - Classic workers cannot touch
document/window - Use Blob URLs for single-file demos; prefer http(s) for real
worker.js - Drag and Drop was pointer move/label; this lesson is background compute + messages
- Next: HTML SSE for server-pushed events
🧠 Test Your Knowledge
Test Your Knowledge
Challenge yourself with this interactive quiz and see how well you understand the topic
📝 Instructions
- Read each question carefully
- Select the best answer for each question
- You can retake the quiz as many times as you want
- Your progress will be shown at the top