EMZETT.
Увійти

Веб-воркери: винесення обчислювального навантаження з основного потоку

Коротко: Веб-воркер виконує JavaScript у власному потоці, щоб важкі обчислення не заморожували інтерфейс; обмін відбувається через повідомлення.

Докладніше: JavaScript у браузері зазвичай працює в основному потоці, який також відповідає за відображення та ввід. Довгий цикл (обробка зображення, розбір великого JSON, побудова пошукового індексу) змушує сторінку підгальмовувати/зависати і погіршує INP. Допомагає воркер.

Подробиці

Виділений воркер

// main.js
const worker = new Worker(new URL('./compute.js', import.meta.url), { type: 'module' });
worker.postMessage({ numbers: bigList });
worker.onmessage = (e) => show(e.data.sum);
// compute.js
self.onmessage = (e) => {
  const sum = e.data.numbers.reduce((a, b) => a + b, 0);
  self.postMessage({ sum });
};

У воркера немає доступу до DOM і window, але є до fetch, IndexedDB, WebAssembly, crypto, таймерів. Дані копіюються структурованим клонуванням; великі буфери як transferable (postMessage(buf, [buf])) переміщуються замість копіювання або розділяються через SharedArrayBuffer (потрібна ізоляція cross-origin).

Види

  • Виділений воркер: належить одній сторінці.
  • Спільний воркер: використовується кількома вкладками.
  • Service worker: мережевий проксі/офлайн/push (окрема тема).
  • Worklet’и (аудіо/малювання) для особливих завдань відображення.
  • OffscreenCanvas: малювання у воркері (ігри/графіка).

Бібліотеки: Comlink перетворює виклики воркера на звичайні async-функції; Vite/Webpack збирають файли воркерів.

Коли це варте того

Варте: обробка зображень/аудіо/відео, розбір/стиснення, криптографія, програми WASM (Python у Pyodide, емулятори), пошук/індекс, розрахунок фізики в іграх, синтаксичний аналіз у редакторах. Не варте: дрібниці (витрати на запуск і копіювання), робота з DOM (у воркері неможлива). Як альтернатива розбивайте довгу роботу на частини (requestIdleCallback, scheduler.yield()), щоб основний потік міг дихати.

Практика

  • Перехоплюйте помилки (worker.onerror), скасовуйте (worker.terminate()), прогрес — через повідомлення.
  • Підлаштовуйте кількість воркерів під ядра (navigator.hardwareConcurrency), повторно використовуйте пул.
  • Безпека: код воркера з того самого джерела, враховуйте CSP worker-src; перевіряйте повідомлення.
  • Налагодження: DevTools показують воркери як окремі потоки.
  • У Node.js є worker_threads, у Python — multiprocessing (та сама ідея: паралелізм без спільного стану).

Див. також: Service worker, Цикл подій, Lighthouse і Core Web Vitals