Запропонувати правкуПокращити цю статтюДопрацюйте відповідь до «Що робить Web Worker?». Ваші зміни проходять модерацію перед публікацією.Потрібне підтвердженняКонтентЩо ви змінюєте🇺🇸EN🇺🇦UAПереглядЗаголовок (UA)Коротка відповідь (UA)**Web Worker** - це окремий потік виконання JavaScript-коду, що працює паралельно з основним потоком (UI thread). **Ключове:** він не блокує інтерфейс і може виконувати важкі обчислення, а потім передавати результат назад в основний потік.Показується над повною відповіддю для швидкого нагадування.Відповідь (UA)Зображення## Що таке Web Worker > **Web Worker** - це окремий потік виконання JavaScript-коду, > що працює **паралельно з основним потоком (UI thread)**. Він **не блокує інтерфейс** і може виконувати важкі обчислення, а потім передавати результат назад в основний потік. ## Проблема без Web Worker JavaScript у браузері **однопотоковий** - усе виконується в одному потоці: - рендеринг сторінки - обробка подій - виконання твого коду Якщо в цьому потоці запустити важкий цикл: ```javascript for (let i = 0; i < 1e9; i++) {} console.log('Готово!'); ``` сторінка "завмре" - інтерфейс перестане реагувати, поки цикл не закінчиться, тому що **Event Loop** зайнятий. ## Рішення - Web Worker За допомогою Web Worker ти можеш винести цей розрахунок **в окремий потік**: ```javascript // main.js const worker = new Worker('worker.js'); worker.postMessage(1e9); // відправляємо задачу worker.onmessage = (event) => { console.log('Результат:', event.data); }; ``` ```javascript // worker.js onmessage = (event) => { let sum = 0; for (let i = 0; i < event.data; i++) sum += i; postMessage(sum); // відправляємо результат назад }; ``` Тепер важкий розрахунок виконується **у фоні**, а UI залишається відгукливим. ## Як працює під капотом 1. Основний потік створює воркера через `new Worker('script.js')`. 2. Браузер запускає **окремий потік JS**. 3. Спілкування між потоками йде через **повідомлення** (message passing). 4. Передача - **асинхронна**, дані серіалізуються (structured clone). 5. Воркер не має доступу до DOM, `window` і `document`. ## Обмін даними (message passing) Комунікація йде через події `postMessage` і `onmessage`: ```javascript // 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 об'єкти**, щоб передавати без копіювання ## Односторонні обмеження Web Worker **ізольований**: - немає доступу до `document`, `window`, `alert()`, `localStorage` - є доступ до: `fetch`, `XMLHttpRequest`, `WebSocket`, `setTimeout`, `indexedDB`, `crypto` тощо ## Види Web Workers | Тип | Де використовується | Особливості | | --- | --- | --- | | **Dedicated Worker** | Один на одного | Працює лише зі скриптом, що його створив | | **Shared Worker** | Кілька вкладок/скриптів | Один воркер для всіх сторінок (за origin + URL) | | **Service Worker** | Між браузером і мережею | Кешує запити, працює навіть офлайн | ## Приклад Shared Worker ```javascript // shared-worker.js onconnect = (event) => { const port = event.ports[0]; port.onmessage = (e) => { port.postMessage(`Отримано: ${e.data}`); }; }; ``` Кілька вкладок можуть підключатися до одного Shared Worker - наприклад, для обміну даними між вкладками. ## Service Worker (особливий тип) > Service Worker - це не просто потік, а "проксі" між браузером і мережею. Він перехоплює HTTP-запити, кешує відповіді і дозволяє працювати **офлайн**. (Приклад: PWA-застосунки, push-сповіщення, фонові синхронізації.) ## Приклад для Service Worker ```javascript // service-worker.js self.addEventListener('fetch', (event) => { event.respondWith( caches.match(event.request).then((cached) => { return cached || fetch(event.request); }) ); }); ``` Це означає: якщо є закешована відповідь - віддати її, інакше завантажити з мережі і зберегти. ## Потокова обробка даних у воркері Воркер може використовувати Streams і Fetch API: ```javascript onmessage = async (e) => { const response = await fetch(e.data.url); const text = await response.text(); postMessage(text.length); }; ``` Так можна обробляти мережеві дані у фоні, взагалі не блокуючи UI. ## Приклад "паралельних" обчислень ```javascript 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('Готово:', result); }; }); ``` Так можна розподілити обчислення між кількома потоками ("псевдопаралелізм"). ## Коли варто використовувати Web Workers | Сценарій | Чому корисно | | --- | --- | | Складні обчислення | парсинг JSON, криптографія, машинне навчання | | Обробка великих даних | фільтрація/агрегація масивів, обробка CSV | | Робота із зображеннями | стиснення, фільтри, генерація прев'ю | | Ігри / анімація | розрахунки фізики без лагів інтерфейсу | | WebSocket + аналіз даних | потокова обробка | ## Проста аналогія > Уяви, що браузер - це кухня. > > - Основний потік (головний JS) - кухар, який готує страву й обслуговує гостей. > - Web Worker - помічник на іншій кухні, який нарізає овочі. > > Кухар дає завдання -> помічник виконує у фоні -> повертає результат. > Ніхто нікому не заважає. ## Підсумок | Компонент | Що робить | | --- | --- | | **Web Worker** | Окремий потік для виконання коду | | **Головна перевага** | Не блокує UI | | **Обмін даними** | Через `postMessage` / `onmessage` | | **Обмеження** | Немає доступу до DOM, `window`, `document` | | **Типи** | Dedicated, Shared, Service Worker | | **Основні застосування** | Фонові обчислення, кеш, офлайн-режим, синхронізація |Для рев’юераПримітка для модератора (необов’язково)Бачить лише модератор. Прискорює рев’ю.