Web Workers представляют собой механизм параллельного выполнения JavaScript-кода в браузере. Основное назначение — перенос ресурсоёмких вычислений из основного потока (UI-потока) в отдельный поток, чтобы не блокировать интерфейс пользователя. Каждый воркер работает в своём изолированном контексте и не имеет прямого доступа к DOM. Взаимодействие с основным потоком происходит через передачу сообщений.
Для создания воркера используется конструктор Worker,
которому передаётся путь к JS-файлу:
const worker = new Worker('worker.js');
Внутри worker.js код выполняется в отдельном потоке. Для
получения данных от основного потока используется событие
message:
self.addEventListener('message', event => {
const data = event.data;
const result = heavyComputation(data);
self.postMessage(result);
});
Основной поток отправляет данные и принимает результат через методы
postMessage и обработчик события message:
worker.postMessage({ value: 42 });
worker.addEventListener('message', event => {
console.log('Результат из воркера:', event.data);
});
Данные между основным потоком и воркером передаются по копированию, а не по ссылке. Это значит, что изменения объекта в воркере не повлияют на объект в основном потоке. Для оптимизации передачи больших бинарных данных можно использовать Transferable Objects:
const buffer = new ArrayBuffer(1024);
worker.postMessage(buffer, [buffer]); // buffer теперь "перемещён" в воркер
После такой передачи исходный buffer в основном потоке
становится недоступным.
Метрики Web Vitals, такие как Largest Contentful Paint (LCP), First Input Delay (FID), Cumulative Layout Shift (CLS), требуют анализа событий, происходящих в основном потоке. Однако часть вычислений, например обработка массивов с данными производительности, может быть вынесена в воркер. Структура передачи работы может быть следующей:
PerformanceObserver:const observer = new PerformanceObserver(list => {
const entries = list.getEntries();
worker.postMessage(entries); // передача воркеру
});
observer.observe({ type: 'largest-contentful-paint', buffered: true });
self.addEventListener('message', event => {
const entries = event.data;
const metrics = calculateMetrics(entries);
self.postMessage(metrics);
});
Для управления жизненным циклом воркера следует учитывать обработку ошибок и освобождение ресурсов:
worker.addEventListener('error', event => {
console.error('Ошибка в воркере:', event.message);
});
worker.terminate(); // принудительное завершение работы воркера
Использование terminate важно после завершения
вычислений, чтобы не держать лишние потоки и не расходовать память
браузера.
importScripts(), что позволяет использовать библиотеки для
сложных вычислений.В контексте Web Vitals воркеры применяются для:
performance без
блокировки UI.Такой подход позволяет одновременно поддерживать гладкий интерфейс и получать точные показатели производительности в реальном времени.