Коротка відповідь
middleWeb worker – це окремий потік, який працює у фоновому режимі. Дані між worker’ом і головним потоком обмінюються через `postMessage`/`onmessage`, використовуючи *structured clone algorithm*; об’єкти копіюються, а не передаються за посиланням. Для комунікації між worker’ами застосовується `MessageChannel` або `postMessage` з посиланням на інший worker, що дозволяє створювати мережу воркерів без прямого доступу до DOM.
Повне пояснення
Що це і навіщо
Web worker – це окремий виконуваний контекст, який дозволяє виконувати довгі обчислення або асинхронні операції без блокування UI‑потоку. Це корисно для розрахунків, парсингу великих файлів, роботи з WebSocket тощо.
Ключові принципи
- Isolated context – worker не має доступу до
window, DOM, глобальних змінних. - Message passing – обмін даними відбувається через
postMessage/onmessage. - Structured clone algorithm – копіює об’єкти, підтримує
ArrayBuffer,Blob,File,ImageBitmapтощо. - Transferable objects – можна передати власність на
ArrayBufferабоMessagePort, що зменшує копіювання.
Як це працює
- Головний потік створює worker:
const w = new Worker('worker.js');. - Для надсилання даних викликається
w.postMessage(data);. - У worker‑і обробляємо:
self.onmessage = e => { /* ... */ };. - Для відповіді:
self.postMessage(result);. - У головному потоці обробляємо:
w.onmessage = e => { /* ... */ };.
Практика і реалізація
// main.js
const worker = new Worker('worker.js');
worker.postMessage({cmd: 'sum', nums: [1,2,3]});
worker.onmessage = e => console.log('Result:', e.data);
// worker.js
self.onmessage = e => {
const {cmd, nums} = e.data;
if (cmd === 'sum') {
const res = nums.reduce((a,b)=>a+b,0);
self.postMessage(res);
}
};
Комунікація між worker’ами
- MessageChannel: створюємо канал і передаємо один порт одному worker’у, інший – іншому.
- postMessage з посиланням на worker:
workerA.postMessage({cmd:'msg', port:portB});.
// main.js
const w1 = new Worker('w1.js');
const w2 = new Worker('w2.js');
const channel = new MessageChannel();
w1.postMessage({port: channel.port1}, [channel.port1]);
w2.postMessage({port: channel.port2}, [channel.port2]);
Тестування
- Jest: мокати
Workerі перевіряти викликиpostMessage. - Vitest: використовувати
workerize-loaderдля реального воркера.
Безпека
- Воркери не мають доступу до
document, тому XSS‑ризики зменшуються. - Переконайтеся, що передані дані не містять небажаних скриптів.
Переваги та обмеження
- Перевага: паралельна обробка, не блокує UI.
- Обмеження: немає доступу до DOM, обмежений розмір пам’яті, копіювання великих об’єктів може бути дорогим.
Чеклист діагностики
- Worker не створюється – перевірте шлях до файлу.
- onmessage не виконується – переконайтеся, що
selfвикористовується у worker‑і. - Дані не приходять – перевірте, що об’єкт підтримується алгоритмом clone.
- Перевищення пам’яті – використовуйте transferable objects (
ArrayBuffer).