Що робить SharedWorker?
Що таке SharedWorker
SharedWorker - це потік JavaScript, який можуть використовувати кілька контекстів (вкладок, iframe, вікон) одночасно, якщо вони завантажені з одного
origin(протокол + хост + порт).
На відміну від звичайного Worker, який "гине" при закритті вкладки, SharedWorker живе, поки хоча б одне вікно залишається підключеним.
Відмінність від звичайного Web Worker
| Особливість | Worker (Dedicated) | SharedWorker |
|---|---|---|
| Використовується | Однією сторінкою | Кількома вкладками/вікнами |
| Створюється | new Worker('worker.js') | new SharedWorker('worker.js') |
| Канал зв'язку | postMessage напряму | Через об'єкт port |
| Час життя | Поки відкрита вкладка | Поки підключений хоча б один контекст |
| Доступний з інших вкладок | Ні | Так (якщо один origin) |
Приклад роботи SharedWorker
1. Код у shared-worker.js
// shared-worker.js
onconnect = (event) => {
const port = event.ports[0];
console.log('Нове підключення');
port.postMessage('Привіт, вкладко!');
port.onmessage = (e) => {
console.log('Повідомлення від вкладки:', e.data);
// Надсилаємо відповідь назад
port.postMessage(`Отримано: ${e.data}`);
};
};2. Код на кожній вкладці (main.js)
// main.js
const shared = new SharedWorker('shared-worker.js');
const port = shared.port;
// Активуємо канал
port.start();
// Слухаємо відповіді від воркера
port.onmessage = (e) => {
console.log('Відповідь від SharedWorker:', e.data);
};
// Надсилаємо повідомлення воркеру
port.postMessage('Привіт від вкладки!');Що станеться:
- Усі вкладки підключаться до одного й того самого воркера;
- Усі вони отримуватимуть повідомлення через свої
port; - Воркер може координувати їх (наприклад, розсилати спільні дані всім).
Як працює onconnect
Коли нова вкладка створює new SharedWorker(), браузер не створює новий потік, якщо воркер уже існує.
Він просто викликає подію onconnect, передаючи туди об'єкт MessagePort, який представляє канал зв'язку.
Таким чином, один SharedWorker може керувати десятками портів (вкладок).
Приклад мовлення всім вкладкам
// shared-worker.js
const ports = [];
onconnect = (e) => {
const port = e.ports[0];
ports.push(port);
port.start();
port.onmessage = (event) => {
// Розсилаємо повідомлення всім підключеним вкладкам
for (const p of ports) {
p.postMessage(`Від вкладки: ${event.data}`);
}
};
};Тепер, якщо ти відкриєш дві вкладки:
- вкладка 1 надішле
port.postMessage("Привіт"), - обидві вкладки отримають
"Від вкладки: Привіт".
Це вже реальний чат між вкладками!
Загальний приклад використання
| Сценарій | Чому SharedWorker корисний |
|---|---|
| Спільний чат між вкладками | можна синхронізувати повідомлення |
| Фонова обробка даних | одна вкладка рахує - всі отримують результат |
| Спільна підписка на WebSocket | одне підключення на всі вкладки (економія ресурсів) |
| Спільна кеш/IndexedDB логіка | один фон для всіх |
| Синхронізація стану | наприклад, спільний токен авторизації між вкладками |
Як взаємодіє SharedWorker
[ Вкладка 1 ] [ Вкладка 2 ] [ Iframe ]
│ │ │
└─────▶ [ SharedWorker Thread ] ◀─────┘
▲ │
│ (ports[])
▼
обробка логікиУсі вкладки підключаються до одного потоку воркера. Воркер обмінюється повідомленнями з кожною вкладкою через її port.
Що важливо пам'ятати
- SharedWorker працює лише в межах одного origin (
https://example.com≠http://example.com). - Не підтримується в Service Workers (це різні типи воркерів).
- Не працює в деяких старих браузерах або в Safari iOS.
- Спілкування відбувається через
port.postMessage()іport.onmessage.
Безпека
- Воркери ізольовані - не мають доступу до DOM,
window,document. - Дані передаються за копією (structured clone).
- Можна використовувати Transferable-об'єкти (
ArrayBuffer) для швидкого обміну.
Проста аналогія
Уяви, що SharedWorker - це офісний сервер у компанії.
Кожен співробітник (вкладка) може підключитися до сервера. Сервер зберігає спільні дані і розсилає оновлення всім. Поки хоча б один співробітник працює - сервер живе.
Коли всі закрили вкладки → сервер автоматично вимикається.
Підсумок
| Особливість | Опис |
|---|---|
| Що робить | Дозволяє кільком сторінкам (вкладкам) одного сайту використовувати спільний потік JS |
| Головна перевага | Поділ логіки і даних між вкладками |
| Комунікація | Через MessagePort (port.postMessage / port.onmessage) |
| Життєвий цикл | Поки відкритий хоча б один клієнт |
| Немає доступу до DOM | Лише обмін повідомленнями |
| Типові сценарії | Спільний WebSocket, кеш, синхронізація стану, міжвкладковий чат |
Коротка відповідь
Для співбесідиКоротка відповідь допоможе вам впевнено відповідати на цю тему під час співбесіди.