Web Workers у JavaScript
Web Worker це окремий потік виконання JavaScript-коду, який працює паралельно з головним потоком (UI thread). Він не блокує інтерфейс: важкі обчислення виконуються у фоні, а результат повертається в головний потік повідомленням.
Теорія
TL;DR
- JavaScript у браузері однопотоковий: рендеринг, обробка подій і ваш код живуть в одному потоці.
- Важкий синхронний цикл займає Event Loop, і сторінка «замерзає».
- Web Worker виносить обчислення в окремий потік, тому UI лишається чуйним.
- Спілкування між потоками йде тільки через повідомлення:
postMessageтаonmessage, дані серіалізуються алгоритмом structured clone. - Воркер не має доступу до
document,window,alert(),localStorage, але маєfetch,XMLHttpRequest,WebSocket,setTimeout,indexedDB,crypto. - Типів три: Dedicated Worker, Shared Worker, Service Worker.
Швидкий приклад
// main.js
const worker = new Worker('worker.js');
worker.postMessage(1e9); // надсилаємо задачу
worker.onmessage = (event) => {
console.log('Result:', event.data);
};// worker.js
onmessage = (event) => {
let sum = 0;
for (let i = 0; i < event.data; i++) sum += i;
postMessage(sum); // повертаємо результат назад
};Тепер важкий розрахунок виконується у фоні, а UI лишається чуйним.
Проблема однопотокового JavaScript
JavaScript у браузері однопотоковий, тобто в одному потоці відбувається все одразу:
- рендеринг сторінки
- обробка подій
- виконання вашого коду
Якщо в цьому потоці запустити важкий цикл:
for (let i = 0; i < 1e9; i++) {}
console.log('Done!');сторінка «замерзне»: інтерфейс перестане реагувати, доки цикл не закінчиться, бо Event Loop зайнятий.
Як це працює під капотом
- Головний потік створює воркера через
new Worker('script.js'). - Браузер запускає окремий потік JS.
- Спілкування між потоками йде через повідомлення (message passing).
- Передача асинхронна, дані серіалізуються (structured clone).
- Воркер не має доступу до DOM,
windowіdocument.
Обмін даними (message passing)
Комунікація йде через події postMessage і onmessage:
// main.js
worker.postMessage({ action: 'sum', a: 5, b: 7 });
// worker.js
onmessage = (e) => {
if (e.data.action === 'sum') {
postMessage(e.data.a + e.data.b);
}
};Передавати можна:
- рядки, числа, об'єкти
ArrayBuffer,Blob,File,ImageBitmap- навіть Transferable об'єкти, щоб передавати без копіювання
Обмеження та доступне API
Web Worker ізольований:
- немає доступу до
document,window,alert(),localStorage - є доступ до
fetch,XMLHttpRequest,WebSocket,setTimeout,indexedDB,cryptoі подібного
Потокова обробка даних у воркері
Воркер може використовувати Streams і Fetch API:
onmessage = async (e) => {
const response = await fetch(e.data.url);
const text = await response.text();
postMessage(text.length);
};Так можна обробляти мережеві дані у фоні, взагалі не блокуючи UI.
Види Web Workers
| Тип | Де використовується | Особливості |
|---|---|---|
| Dedicated Worker | Один на одного | Працює лише зі скриптом, який його створив |
| Shared Worker | Кілька вкладок або скриптів | Один воркер для всіх сторінок (за origin + URL) |
| Service Worker | Між браузером і мережею | Кешує запити, працює навіть офлайн |
Приклад Shared Worker
// shared-worker.js
onconnect = (event) => {
const port = event.ports[0];
port.onmessage = (e) => {
port.postMessage(`Received: ${e.data}`);
};
};Кілька вкладок можуть під'єднуватися до одного Shared Worker, наприклад щоб обмінюватися даними між вкладками.
Service Worker як окремий тип
Service Worker це не просто потік, а «проксі» між браузером і мережею.
Він перехоплює HTTP-запити, кешує відповіді і дозволяє працювати офлайн. Приклади: PWA-застосунки, push-сповіщення, фонові синхронізації.
// service-worker.js
self.addEventListener('fetch', (event) => {
event.respondWith(
caches.match(event.request).then((cached) => {
return cached || fetch(event.request);
})
);
});Це означає: якщо є закешована відповідь, віддати її, інакше завантажити з мережі.
Приклад «паралельних» обчислень
const workers = Array.from({ length: 4 }, () => new Worker('calc.js'));
let completed = 0;
let result = 0;
workers.forEach((w, i) => {
w.postMessage(i);
w.onmessage = (e) => {
result += e.data;
if (++completed === 4) console.log('Done:', result);
};
});Так можна розподілити обчислення між кількома потоками, це «псевдопаралелізм».
Коли варто використовувати Web Workers
| Сценарій | Чому корисно |
|---|---|
| Складні обчислення | парсинг JSON, криптографія, машинне навчання |
| Обробка великих даних | фільтрація та агрегація масивів, обробка CSV |
| Робота із зображеннями | стиснення, фільтри, генерація мініатюр |
| Ігри та анімація | розрахунки фізики без лагів інтерфейсу |
| WebSocket плюс аналіз даних | потокова обробка |
Проста аналогія:
Уявіть, що браузер це кухня. Головний потік (основний JS) це кухар, який готує страву і обслуговує гостей. Web Worker це помічник на іншій кухні, який нарізає овочі. Кухар дає завдання, помічник виконує його у фоні і повертає результат. Ніхто нікому не заважає.
Підсумок:
| Компонент | Що робить |
|---|---|
| Web Worker | Окремий потік для виконання коду |
| Головна перевага | Не блокує UI |
| Обмін даними | Через postMessage / onmessage |
| Обмеження | Немає доступу до DOM, window, document |
| Типи | Dedicated, Shared, Service Worker |
| Основні застосування | Фонові обчислення, кеш, офлайн-режим, синхронізація |
Типові помилки
- Звертатися до
documentчиwindowусередині воркера. Їх там немає, потрібні дані треба передати повідомленням. - Чекати, що об'єкт передасться за посиланням. Дані копіюються через structured clone, тож великі масиви краще віддавати як Transferable (
ArrayBuffer), інакше копіювання само по собі стане вузьким місцем. - Передавати у
postMessageфункції, DOM-вузли або класи з методами. Structured clone їх не підтримує і кине помилку. - Створювати новий воркер на кожен дрібний виклик. Запуск потоку коштує часу і пам'яті, воркери варто перевикористовувати або тримати їх пул.
- Плутати Web Worker і Service Worker. Перший для обчислень, другий для перехоплення мережевих запитів і офлайн-режиму.
- Забувати
worker.terminate(). Воркер живе, доки його явно не зупинили або доки відкрита сторінка.
Коротка відповідь
Для співбесідиКоротка відповідь допоможе вам впевнено відповідати на цю тему під час співбесіди.