Web Workers
↑ 7.4 Browser API · ← Предыдущая · → Следующая
Зачем это на собесе
Единственный способ настоящей многопоточности в браузере; спрашивают, что можно вынести и как передавать данные.
Зачем
JavaScript однопоточный: тяжёлое вычисление блокирует UI. Worker выполняет код в отдельном потоке без доступа к DOM.
// worker.ts
self.onmessage = (e: MessageEvent<number[]>) => {
const sorted = [...e.data].sort((a, b) => a - b)
self.postMessage(sorted)
}
// main.ts
const worker = new Worker(new URL('./worker.ts', import.meta.url), { type: 'module' })
worker.postMessage(bigArray)
worker.onmessage = e => { result.value = e.data }
// worker.terminate()Что переносить
Парсинг больших файлов (CSV, JSON), сортировка и фильтрация больших коллекций, сжатие, шифрование, обработка изображений, WASM-вычисления, markdown/подсветка.
Передача данных
- Structured clone — копирование (дорого для больших данных);
- Transferable objects (
ArrayBuffer) — передача владения без копии:postMessage(buf, [buf]); SharedArrayBuffer+Atomics— общая память (требует cross-origin isolation);- Comlink превращает обмен сообщениями в вызовы функций.
import { wrap } from 'comlink'
const api = wrap<import('./worker').Api>(new Worker(new URL('./worker.ts', import.meta.url), { type: 'module' }))
const result = await api.heavy(data)Виды воркеров
| Вид | Назначение |
|---|---|
| Dedicated Worker | один владелец |
| Shared Worker | общий для вкладок |
| Service Worker | прокси сети, offline, push |
| Worklet | аудио, отрисовка |
Нюансы
- нет DOM,
window,document; естьfetch,IndexedDB,WebSocket; - накладные расходы старта — пул воркеров для частых задач;
- реактивные объекты Vue нельзя передавать (Proxy не клонируется):
toRaw; - OffscreenCanvas позволяет рисовать в воркере.
Вопросы с ответами
Что можно передать без копирования?
Transferable-объекты (ArrayBuffer, MessagePort, ImageBitmap): владение переходит к воркеру, у отправителя буфер становится пустым.
Почему worker не может менять DOM?
Он работает в отдельном потоке без доступа к документу; результат отправляется в главный поток, который и обновляет UI.