Для чего используются Web Worker в JavaScript
Что проверяют
Понимаете ли вы, что JavaScript на странице выполняется в одном главном потоке вместе с отрисовкой и обработкой ввода, и какую работу воркер из этого потока забирает. Следом обычно спрашивают про цену передачи данных и чем Web Worker отличается от Service Worker.
Как отвечать
Суть: воркер это отдельный поток со своим event loop и глобальным объектом self. Тяжёлый расчёт в главном потоке замораживает интерфейс и портит INP, в воркере интерфейс остаётся отзывчивым. Дальше разновидности:
- Dedicated Worker: принадлежит одной странице, основной случай;
- SharedWorker: общий для вкладок одного origin, например одно соединение на все вкладки;
- Service Worker: другая задача. Это прокси между страницей и сетью для офлайна, кэша и push, для вычислений его не используют.
Затем ограничения и передача данных. В воркере нет DOM, window и localStorage, зато есть fetch, IndexedDB, WebSocket и OffscreenCanvas. Общение идёт через postMessage, данные копируются алгоритмом structured clone: функции и DOM-узлы передать нельзя, будет DataCloneError. Большие буферы передают вторым аргументом как transferable (ArrayBuffer, ImageBitmap), тогда они переходят без копирования, а у отправителя становятся пустыми. Общая память через SharedArrayBuffer и Atomics доступна только при cross-origin isolation, для неё нужны заголовки COOP и COEP.
Подключение в современном сборщике: new Worker(new URL('./worker.ts', import.meta.url), { type: 'module' }), этот шаблон понимают Vite и webpack 5. Чтобы не писать протокол сообщений руками, берут Comlink.
Типичные задачи: разбор больших JSON и CSV, обработка изображений, поиск по индексу на клиенте, подсветка синтаксиса, вычисления на WebAssembly.
Где спотыкаются
Выносят в воркер сетевые запросы «для скорости». fetch и так не блокирует главный поток, выигрыша нет.
Гоняют большие объекты туда и обратно на каждый кадр без transferable. Копирование съедает весь выигрыш, а на мелких задачах запуск воркера и сериализация стоят дороже самой работы.
Путают с Service Worker или ждут, что воркер сможет поменять DOM напрямую.