Loading...

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.

Blob Worker compute round-trip

html
<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.createObjectURL builds a worker script URL without a second file
  • new Worker(url) starts a background script for this page
  • postMessage(40) sends a number into the worker
  • Worker onmessage runs the loop and postMessages the sum back
  • Page onmessage writes into <pre> — DOM stays on the main thread
  • Unlike Drag and Drop, nothing uses draggable or dataTransfer — 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.

Worker replies; page updates DOM

html
<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 document calls
  • Page onmessage assigns msg.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

  1. Paste the Blob sum demo; click the button; confirm the sum appears.
  2. Change 40 to another small n; confirm the result changes.
  3. Paste the echo demo; confirm the paragraph updates only after the worker replies.
  4. (Optional) Skim a real worker.js file pattern: page new Worker("worker.js") when you serve over http(s).
  5. Write one sentence: Drag and Drop moves/labels with pointer events; Web Workers compute off-thread via messages.
  6. Prefer http(s) or Blob demos over relying only on file:// if a Worker URL fails.
  7. Peek ahead: SSE (Server-Sent Events) pushes updates from the server — not background CPU workers.

Easy mistakes

  • Expecting document.querySelector to 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.js from incompatible origins or fragile file:// paths
  • Forgetting to handle onmessage on the page so results never appear
  • Treating Blob demos as the only production pattern (real apps often use a .js file 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

Ready to Start

Test Your Knowledge

Challenge yourself with this interactive quiz and see how well you understand the topic

❓
5
Questions
🎯
70%
To Pass
♾️
∞
Time
🔄
∞
Attempts

📝 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