Artikel

Web Workers — Parallel JavaScript uden main thread-blokning

Web Workers kører JavaScript i en baggrundstråd. Main thread forbliver fri til brugerinteraktion — INP forbedres. Workers kan ikke tilgå DOM men kommunikerer via postMessage.

JavaScript er single-threaded: al eksekvering foregår på main thread, og lange JavaScript-operationer blokerer UI-opdateringer og brugerinteraktion direkte. Web Workers løser dette ved at flytte CPU-intensiv beregning til en separat baggrundstråd, så main thread forbliver responsiv. For SEO og Core Web Vitals er Workers relevante fordi de reducerer long tasks og forbedrer INP (Interaction to Next Paint) — den Core Web Vitals-metric der måler responsivitet ved brugerinteraktion og er en direkte Google rankingfaktor.

Hvornår Web Workers er løsningen

Workers hjælper når du har CPU-intensive opgaver der tager over 50ms og ikke er afhængige af DOM:

  • Parsning af store JSON-datasæt
  • Kryptografiske operationer
  • Billedbehandling (pixelmanipulation via canvas)
  • Søgeindeksering (Pagefind kører bl.a. sin søgemaskine i Workers)
  • Dataanalyse og aggregering
  • Komprimering/dekomprimering

Workers hjælper ikke for operationer der kræver DOM-adgang (brug requestAnimationFrame i stedet) eller for I/O-bound operationer der allerede er asynkrone.

Grundlæggende Worker API

Opret en Worker:

// main.js
const worker = new Worker('/worker.js');

worker.postMessage({ data: largeDataset, operation: 'process' });

worker.onmessage = (event) => {
  const result = event.data;
  updateUI(result);  // DOM-opdatering sker stadig på main thread
};

worker.onerror = (error) => console.error(error);
// worker.js
self.onmessage = (event) => {
  const { data, operation } = event.data;

  // Tung beregning — blokerer ikke main thread
  const result = processData(data);

  self.postMessage(result);
};

Transferable Objects — undgå datakopi-overhead

postMessage kopierer data som standard (structured clone). For store datasets er dette dyrt. Transferable Objects overfører ownership af data uden kopi — zero-copy transfer:

const buffer = new ArrayBuffer(1024 * 1024 * 10);  // 10 MB

// Kopierer data — langsomt for store buffere
worker.postMessage(buffer);

// Overfører ownership — øjeblikkeligt, buffer er nu tom i main thread
worker.postMessage(buffer, [buffer]);

ArrayBuffer, MessagePort og OffscreenCanvas er transferable.

SharedArrayBuffer — delt hukommelse

SharedArrayBuffer deler hukommelse mellem main thread og Workers uden kopi. Kræver COOP/COEP headers (Cross-Origin Isolation):

const sharedBuffer = new SharedArrayBuffer(1024);
const sharedArray = new Int32Array(sharedBuffer);

worker.postMessage({ buffer: sharedBuffer });
// Begge threads læser/skriver til samme hukommelse
// Brug Atomics for thread-safe operationer

Worker Pools

For gentagne opgaver er det ineffektivt at oprette og terminere Workers per opgave. En Worker Pool genanvender Workers:

class WorkerPool {
  constructor(url, size = navigator.hardwareConcurrency || 4) {
    this.workers = Array.from({ length: size }, () => new Worker(url));
    this.queue = [];
    this.available = [...this.workers];
  }

  run(data) {
    return new Promise((resolve) => {
      const execute = () => {
        const worker = this.available.pop();
        worker.onmessage = (e) => {
          this.available.push(worker);
          resolve(e.data);
          if (this.queue.length) this.queue.shift()();
        };
        worker.postMessage(data);
      };
      this.available.length ? execute() : this.queue.push(execute);
    });
  }
}

INP-effekten

En 200ms JSON-parsing operation på main thread resulterer i 200ms long task og dårlig INP. Flytning til Worker reducerer main thread-bidrag til postMessage-kald (< 1ms) og onmessage-callback (< 1ms). Brugerinteraktion forbliver responsiv under hele operationen.

Biblioteker som Comlink (Google) abstraherer Worker-kommunikation til normale async funktionskald og eliminerer manuel postMessage-håndtering. → Denne artikel er en del af Web Performance — Core Web Vitals og teknisk hastighed.

Andre artikler i samme emne

Ofte stillede spørgsmål

Hvad kan Web Workers ikke gøre?
Web Workers har ingen adgang til DOM, window, document eller lokationsbaserede browser-APIs. De kan ikke direkte manipulere siden. Al kommunikation foregår via postMessage og strukturerede data-kopi (eller SharedArrayBuffer for shared memory). Workers egner sig til beregning, databehandling og netværkskald — ikke til UI-opdateringer.
Hvad er forskellen på Web Workers, Service Workers og Worklets?
Web Workers er generelle baggrundstråde til vilkårlig JavaScript-beregning. Service Workers er en specialiseret Worker der intercepter netværkskald og muliggør offline caching og push notifications. Worklets (Audio Worklet, Paint Worklet, Animation Worklet) er letvægtsudvidelser til browser-rendering pipelines med meget begrænset API-adgang.
Hvornår er Web Workers den rigtige løsning frem for async/await?
Async/await og Promises løser I/O-bound asynkronitet: netværkskald, fil-læsning og timeouts. Web Workers løser CPU-bound beregning: parsing af store datasæt, kryptografi, billedbehandling. Hvis en opgave tager 50+ ms og er CPU-intensiv (ikke venter på netværk) er Web Workers den rigtige løsning. Et langt database-kald løses med async/await — et 200ms JSON-parse løses med Web Workers.
Er Web Workers relevante for SEO og Core Web Vitals?
Indirekte men reelt. Web Workers forbedrer INP (Interaction to Next Paint) ved at reducere long tasks på main thread — og INP er en Core Web Vitals-rankingfaktor. Applikationer med tung JavaScript-beregning der blokerer brugerinteraktion i 200-500ms kan forbedre INP markant ved at flytte beregningen til Workers. Det er ikke en direkte crawling-SEO-faktor men en direkte rankingfaktor via Core Web Vitals.
Hvad er Comlink og hvornår er det nyttigt?
Comlink er Googles JavaScript-bibliotek der abstraherer Web Worker kommunikation til normale async funktionskald. I stedet for manuel postMessage-håndtering kan du kalde Worker-funktioner som om de er lokale async-funktioner. Det eliminerer en stor mængde boilerplate-kode og gør Workers langt mere vedligeholdelsesvenlige. Comlink er ideel til projekter der bruger Workers til komplekse beregningsopgaver med mange dataudvekslinger.

Placering i ordbogen

Web Workers — Parallel JavaScript uden main thread-blokning