awesome-everything EN
↑ Обратно к восхождению

Браузер и фронтенд-рантайм

Что такое воркеры и зачем они нужны

Суть Воркеры запускают JavaScript вне главного потока — web workers вычисляют, service workers проксируют сеть, оба с жёсткой границей, которую DOM не пересекает.
Высота — путь к senior
НольJuniorMiddleSenior
Ты на junior-высоте — поверхность
◷ 10 min

Запарсите JSON-файл на 5 МБ на главном потоке — и страница замирает на ~150 мс: пропущенные кадры, неотзывчивые кнопки. Ответ браузера — не «ускорить поток». Ответ — «дать вам больше потоков».

Проблема главного потока

У браузера один поток на JavaScript, компоновку, отрисовку и ввод. Пока он занят, ничего больше не работает. Парсить большой файл, считать хэш или фильтровать огромный датасет на главном потоке — значит тормозить любую анимацию и любой отклик на всё это время.

Ответ браузера — выполнение вне главного потока: воркеры. Существует четыре вида, каждый для своей работы:

  • Web worker — второй JS-поток для CPU-bound работы (парсинг, крипто, обработка изображений). Нет DOM, нет window, нет document.
  • Service worker — сетевой прокси, сидящий между страницей и сервером. Перехватывает запросы, отдаёт закешированные ответы, переживает закрытие страницы.
  • Worklet — крошечный хук в пайплайн рендеринга или аудио браузера (paint worklet, audio worklet). Ещё более ограничен, чем воркер.
  • SharedArrayBuffer — общая память между потоками (не воркер сам по себе, но побег из message-passing). За гейтом заголовков cross-origin isolation.
Воркеры с первого взгляда
Старт web worker
5–20 мс
Парсинг 5 МБ JSON, главный поток
~150 мс заморозки
Парсинг 5 МБ JSON, web worker
0 мс джанка
Бюджет кадра при 60 fps
16.67 мс
Кадров пропущено при 150 мс
~9 кадров

Метафора офиса

Главный поток — это вы за своим столом: вы отвечаете на телефон (ввод) и обновляете доску (DOM) сами. Web worker — коллега в задней комнате: вы отправляете ему большой расчёт запиской, он делает его, не трогая ваш стол, присылает ответ запиской. Трогать вашу доску он не может. Только вы можете.

Service worker — почтовая комната: каждое письмо в и из проходит сначала через неё, и она может ответить на некоторые из своего шкафа, не выходя наружу. Продолжает работать, даже когда вы ушли на день.

Антон · Браузер загружает фото для редактирования. Дима · Origin-сервер комментирует: «Применить фильтр — это миллионы пиксельных операций — на главном потоке это 600 мс заморозки. Поэтому мы постим данные изображения в web worker. Воркер перемалывает пиксели на своём потоке; главный поток остаётся свободным. Когда он заканчивает, постит результат обратно, и мы рисуем.»

Фундаментальное правило

Воркеры не имеют никакого доступа к DOM. Глобальный объект воркера — WorkerGlobalScope, в котором нет document, нет window, нет элементов. Это не ограничение, которое надо обходить — это дизайн. Он сохраняет DOM как single-owner и исключает состояния гонки. Воркер может вычислить что отрендерить и вернуть результат, но главный поток должен применить его.

Единственное исключение: OffscreenCanvas. Bitmap-канвас не является частью DOM-дерева — это просто буфер пикселей. Вы можете передать OffscreenCanvas воркеру, и он рисует в него целиком вне главного потока. Всё остальное в DOM — только главный поток.

Расставь шаги по порядку

Страница отдаёт тяжёлый расчёт web worker-у. Расставьте шаги в порядке, в котором они происходят.

  1. 1 Главный поток создаёт воркер: new Worker('calc.js')
  2. 2 Главный поток шлёт входные данные: worker.postMessage(data)
  3. 3 Воркер гоняет расчёт на своём потоке
  4. 4 Воркер шлёт результат обратно: postMessage(result)
  5. 5 Обработчик onmessage главного потока получает результат
Викторина

Почему web worker не может обновить страницу напрямую?

Викторина

Чем service worker отличается от web worker?

Закончи аналогию

В метафоре офиса коллега в задней комнате делает тяжёлые расчёты для вас и отчитывается запиской, но не может тронуть вашу доску. Какой это вид воркера?

Посчитай

Страница парсит JSON-файл на 5 МБ на главном потоке, и это занимает примерно 150 мс. Бюджет кадра при 60 fps — 16.67 мс. Примерно сколько кадров пропускает один этот парсинг?

кадров
Почему это работает

Воркеры появились потому, что JavaScript однопоточен по дизайну — совместное использование изменяемого состояния несколькими потоками требует блокировок, а блокировки в UI-контексте вызывают дедлоки и priority inversion. Модель воркеров избегает всего этого, полностью запрещая общее состояние. У каждого воркера собственный heap, собственные глобалы, собственный event loop. Данные пересекают границу только через postMessage (который копирует их) или через явные примитивы общей памяти (SharedArrayBuffer + Atomics). Ограничение — это гарантия безопасности.

Вспомните перед уходом
  1. 01
    В чём фундаментальная разница между web worker и service worker?
  2. 02
    Почему у воркеров нет доступа к DOM?
  3. 03
    Каково единственное DOM-исключение для воркеров?
Итог

Главный поток браузера — единственный владелец JS-выполнения, компоновки, отрисовки и ввода: всё, что его блокирует, тормозит всю страницу. Воркеры дают дополнительные потоки: web workers для CPU-bound вычислений (нет DOM, общение через postMessage), service workers для сетевого проксирования (перехват fetch, отдача кеша, переживают закрытие страницы). Ни один не может трогать DOM — это ограничение и есть то, что делает их безопасными. Парсинг JSON 150 мс на главном потоке пропускает ~9 кадров при 60 fps; перенесённый в web worker, он ничего не стоит главному потоку.

Связанные уроки
встречается в41
Продолжить восхождение ↑Механика web workers: dedicated, shared и OffscreenCanvas
хоткеи развернуть
поиск
K
пред. пьеса
k
след. пьеса
j
тиры
t
это меню
?
sources3
expand
  1. 01
  2. 02
  3. 03

Trademarks belong to their respective owners. Editorial reference only.