Web Workers: многопоточность в браузере

🤔 Зачем нужны Web Workers?

JavaScript — однопоточный язык. Это значит, что если у вас есть тяжёлая задача (например, обработка 10 000 данных или сложные вычисления), она блокирует интерфейс браузера. Пользователь не сможет кликать кнопки, пока скрипт не завершится.

Web Workers решают эту проблему! Они позволяют запускать код в фоновом потоке, не мешая основному потоку. Это как нанять ассистента, который делает всю грязную работу, пока вы общаетесь с клиентом.

💡 Важно! Web Workers не имеют доступа к DOM. Они работают в изолированном окружении и общаются с основным потоком через сообщения.


🛠️ Как создать Web Worker?

Создадим простого воркера, который считает сумму чисел без блокировки UI.

1. Основной файл (main.js):

// Создаём нового воркера (укажите правильный путь к файлу!)
const worker = new Worker('worker.js');

// Отправляем данные воркеру
worker.postMessage([1, 2, 3, 4, 5]);

// Получаем результат от воркера
worker.onmessage = (event) => {
  console.log('Сумма чисел:', event.data); // => 15
};

2. Файл воркера (worker.js):

// Обрабатываем данные из основного потока
onmessage = (event) => {
  const numbers = event.data;
  const sum = numbers.reduce((a, b) => a + b, 0);

  // Отправляем результат обратно
  postMessage(sum);
};

🔥 Что произошло?
1. Основной поток создал воркера и отправил ему массив чисел.
2. Воркер вычислил сумму и вернул результат.
3. Основной поток получил ответ и вывел его в консоль.


🚀 Когда использовать Web Workers?

Идеальные сценарии: - Обработка больших массивов данных (JSON.parse, Array.map, filter).
- Сложные математические вычисления (например, алгоритмы машинного обучения).
- Декодирование аудио/видео (WebAssembly тоже подходит).
- Долгие синхронные запросы (если нельзя использовать async/await).

⚠️ Осторожно! Создание сотен воркеров — плохая идея. Каждый воркер потребляет память.


🔥 Продвинутые возможности

1. Передача данных без копирования (Transferable Objects)

Если нужно отправить большие данные (например, ArrayBuffer), используйте transfer для экономии памяти:

// Основной поток
const buffer = new ArrayBuffer(1024 * 1024); // 1MB
worker.postMessage(buffer, [buffer]); // Теперь `buffer` нельзя использовать в основном потоке!

2. Воркеры в модулях (ES6)

Современные браузеры поддерживают модульных воркеров:

const worker = new Worker('worker.js', { type: 'module' });

3. SharedWorker — для нескольких вкладок

Если нужно, чтобы воркер работал между вкладками, используйте SharedWorker:

const sharedWorker = new SharedWorker('shared-worker.js');
sharedWorker.port.postMessage('Привет, другая вкладка!');

🛑 Ограничения и подводные камни

  • Нет доступа к DOM (document, window).
  • Нет localStorage (используйте postMessage или IndexedDB).
  • Ограниченный API (например, нельзя использовать alert).

Но есть и хорошие новости:
- ✅ Можно использовать fetch, WebSocket, setTimeout.
- ✅ Поддерживается importScripts() для загрузки дополнительных скриптов.


💡 Практический пример: Параллельная сортировка массива

Допустим, у нас есть 1 000 000 чисел, и мы хотим их отсортировать без блокировки UI.

main.js

const worker = new Worker('sort-worker.js');
const bigArray = Array.from({ length: 1_000_000 }, () => Math.random());

worker.postMessage(bigArray);
worker.onmessage = (event) => {
  console.log('Отсортированный массив:', event.data);
};

sort-worker.js

onmessage = (event) => {
  const sortedArray = event.data.sort((a, b) => a - b);
  postMessage(sortedArray);
};

Теперь сортировка работает в фоне, а UI остаётся отзывчивым!


🎯 Итоги

  • Web Workers ускоряют тяжелые операции, не блокируя интерфейс.
  • Общение между потоками происходит через postMessage.
  • Используйте их для сложных вычислений, но не для работы с DOM.
  • Если нужно что-то мощнее — посмотрите в сторону WebAssembly.

Теперь ты знаешь, как заставить браузер работать на полную! 🚀

Если хочешь глубже разобраться в многопоточности JavaScript, рекомендую глянуть YouTube-канал Данилы Бежина — там есть отличные разборы.

Скрыть рекламу навсегда

🌱 Индвидидулаьные занятия

Индивидуальные онлайн-занятия по программированию для детей и подростков

Личный подход, без воды, с фокусом на понимание и реальные проекты.

🚀 Записаться на занятие