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