[Lv3] Web Worker на практике: фоновые вычисления без блокировки UI
Web Worker переносит ресурсоёмкую логику с основного потока, чтобы UI оставался отзывчивым.
1. Зачем нужен Web Worker?
JavaScript в основном потоке является однопоточным для задач UI. Тяжёлые вычисления могут заморозить взаимодействие.
Типичные кандидаты:
- Парсинг и преобразование больших JSON
- Агрегация/статистика по большим массивам
- Сжатие, шифрование или обработка изображений
2. Базовое использование
Основной поток
const worker = new Worker(new URL('./report.worker.ts', import.meta.url), { type: 'module' });
worker.postMessage({ type: 'AGGREGATE', payload: data });
worker.onmessage = (event) => {
renderChart(event.data);
};
Поток worker'а
self.onmessage = (event) => {
const { type, payload } = event.data;
if (type === 'AGGREGATE') {
const result = compute(payload);
self.postMessage(result);
}
};
3. Паттерны обмена сообщениями
- Запрос/ответ с
requestId - События прогресса для долгих задач
- Канал ошибок со структурированным payload
self.postMessage({ requestId, progress: 60 });
4. Transferable objects для больших бинарных данных
Для больших ArrayBuffer передайте владение, чтобы избежать дорогостоящего копирования.
worker.postMessage({ bytes: buffer }, [buffer]);
5. Паттерн пула worker'ов
Для нескольких тяжёлых задач создайте небольшой пул worker'ов вместо неограниченного порождения.
Преимущества:
- Предсказуемое потребление CPU
- Лучший контроль планирования
- Меньшие накладные расходы на запуск
6. Ограничения и предостережения
- Worker'ы не могут напрямую обращаться к DOM
- Существуют затраты на сериализацию при structured clone
- Отладка сложнее, чем кода основного потока
- Не каждую задачу стоит переносить в worker'ы
7. Очистка
Всегда завершайте, когда worker больше не нужен.
worker.terminate();
Краткое резюме для собеседования
Я использую Web Worker для ресурсоёмких задач, которые блокировали бы взаимодействие. Я проектирую протоколы сообщений, использую transferable objects для больших бинарных данных и контролирую жизненный цикл worker'а с помощью очистки и ограничений пула.