Веб-воркеры: вынос вычислительной нагрузки из основного потока
Коротко: Веб-воркер выполняет 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