Browser Internals
Как работают веб-воркеры? Какие виды бывают?
Web Workers
Основная идея
Воркер — это отдельный поток браузера со своим событийным циклом. Нет доступа к DOM и window. Общение с основным потоком — только через сообщения:
// Основная страница → воркер
worker.postMessage(data);
// Воркер → основная страница
onmessage = (e) => postMessage(e.data);Виды воркеров
Dedicated Worker
const worker = new Worker('script.js');Один владелец (вкладка/скрипт). Для тяжёлых вычислений — парсинг, крипто, обработка изображений.
Shared Worker
const worker = new SharedWorker('script.js');Несколько вкладок могут подключаться к одному воркеру. ⚠️ Поддержка в браузерах ограничена.
Service Worker
navigator.serviceWorker.register('/sw.js');Прокси между сетью и приложением: офлайн, кэш, push-уведомления. Жизненный цикл: install → activate → fetch. Не для тяжёлых вычислений.
Передача данных
| Способ | Как | Когда |
|---|---|---|
| Клонирование | postMessage(data) | По умолчанию, делает копию |
| Transfer | postMessage(data, [data]) | Большие буферы, zero-copy, оригинал становится пустым |
Note
Transfer работает только с
Transferable:ArrayBuffer,MessagePort,OffscreenCanvas,ReadableStream.
Связанные API
Worklet (AudioWorklet, PaintWorklet и др.) — лёгкие мини-воркеры для узких браузерных задач (звук, рисунок в CSS, анимации). Стабильно работают только в Chrome/Edge.
SharedArrayBuffer + Atomics — разделяемая память между потоками. Нужна редко, в основном для WebAssembly/C++. Требует заголовков на сервере:
Cross-Origin-Opener-Policy: same-origin
Cross-Origin-Embedder-Policy: require-corp
Что происходит после ввода URL до появления страницы?
URL → DNS → TCP → TLS → HTTP GET → байты HTML → (парсинг + DOM + CSSOM параллельно) → Render Tree → Layout → Paint → Compositing
1. Кэш-проверка
Проверяется по каждому ресурсу отдельно. DNS-кэш — есть ли IP для домена (если TTL не истёк, DNS lookup пропускается). HTTP-кэш — три варианта: кэш свежий (max-age не истёк) → файл берётся локально; кэш устарел, файл не изменился → сервер отвечает 304 Not Modified; файл изменился → 200 OK, скачивается новый.
2. DNS lookup
Домен превращается в IP-адрес. Порядок: локальный кэш → системный hosts → DNS-сервер провайдера → рекурсивный обход до корневых серверов.
3. TCP handshake Три шага чтобы браузер и сервер убедились что слышат друг друга. SYN — браузер → сервер: «хочу соединение, вот мой стартовый номер пакета». SYN-ACK — сервер → браузер: «принял, я тоже готов, вот мой номер». ACK — браузер → сервер: «принял, начинаем».
4. TLS handshake (только HTTPS) Согласуются алгоритмы шифрования, обмениваются сертификатами и ключами. Начиная с TLS 1.3 — занимает всего 1 round-trip.
5. HTTP GET запрос
Браузер отправляет запрос с заголовками (Host, Accept, Cookie и др.).
6. Сервер возвращает HTML Браузер начинает получать байты ответа.
7. Парсинг HTML = построение DOM Это один инкрементальный процесс: байты → символы (декодирование UTF-8) → токены (теги, атрибуты, текст) → DOM-узлы. Дерево строится по мере получения байт, не после.
Если встречается
<script>безasync/deferили<link rel="stylesheet">— парсер останавливается и ждёт загрузки/исполнения ресурса.
8. Загрузка CSS = построение CSSOM Строится параллельно с DOM. Не блокирует построение DOM, но блокирует рендер.
9. Загрузка остальных ресурсов JS, изображения, шрифты — браузер обнаруживает их по мере парсинга и запрашивает параллельно (Speculative / Preload Scanner).
10. Render Tree
DOM + CSSOM объединяются. Попадают только видимые узлы с вычисленными стилями. display: none — исключается вместе с потомками. visibility: hidden — включается, занимает место. <head>, <script>, <meta> — не попадают, нет визуального представления.
11. Layout (Reflow) Вычисляются точные размеры и позиции каждого элемента на экране.
12. Paint Узлы превращаются в пиксели: цвета, тени, текст, границы — рисуются на слоях.
13. Compositing
Слои склеиваются и выводятся на экран в правильном порядке (z-index, трансформации).
Что такое DNS lookup и как работает кэширование?
DNS lookup — процесс получения IP-адреса по доменному имени.
Уровни кэширования (от ближнего к дальнему):
- Браузерный кэш DNS.
- Кэш операционной системы (
/etc/hostsтоже проверяется). - Кэш роутера.
- Кэш DNS-резолвера провайдера.
- Рекурсивный запрос к корневым DNS-серверам.
У каждой DNS-записи есть TTL (Time To Live) — время, после которого кэш устаревает.
Что такое DOM и CSSOM?
- DOM (Document Object Model) — дерево объектов, построенное из HTML. Каждый тег становится узлом дерева.
- CSSOM (CSS Object Model) — дерево, отражающее все CSS-правила и их приоритеты.
Процесс:
- HTML → токенизация → парсинг → DOM.
- CSS → токенизация → парсинг → CSSOM.
- DOM + CSSOM → Render Tree (только видимые элементы).
display: noneисключает элемент из Render Tree.visibility: hidden— нет.
Что такое layout (reflow)?
Layout — этап вычисления геометрии: размеры, позиции, отступы всех элементов.
Что влияет на layout:
width,height,padding,margin,borderfont-size,line-heightposition,float,flex,grid
Важно: layout — глобальная операция. Изменение одного элемента может затронуть соседей и родителей. Особенно дорого это в больших деревьях.
Что такое painting и compositing?
Painting — браузер рисует каждый элемент попиксельно: текст, фон, границы, тени, градиенты. Результат — набор слоёв.
Compositing — слои собираются в финальное изображение на экране. Часть этой работы выполняет GPU, а не CPU.
Оптимизация: свойства transform и opacity меняются только на этапе compositing, минуя layout и paint — это делает их анимацию наиболее производительной.
Чем reflow отличается от repaint?
| Reflow | Repaint | |
|---|---|---|
| Что пересчитывается | Геометрия (размеры, позиции) | Внешний вид (цвет, тень) |
| Затрагивает соседей | Да, может | Нет |
| Стоимость | Высокая | Средняя |
| Пример | width, margin, font-size | color, background, border-color |
Каждый reflow влечёт repaint, но не наоборот.
Что вызывает reflow и как его минимизировать?
Причины:
- Добавление / удаление / перемещение DOM-узлов.
- Изменение геометрических CSS-свойств.
- Чтение
offsetWidth,scrollTop,getBoundingClientRect()после DOM-изменений. - Ресайз окна браузера.
Как минимизировать:
- Батчить DOM-изменения (менять разом, не по одному).
- Читать layout-свойства до изменений, а не между ними.
- Использовать
documentFragmentдля вставки множества элементов. - Анимировать через
transform/opacityвместоtop/left.
Что такое SPA, как работает, что передаётся с сервера?
SPA (Single Page Application) — веб-приложение, которое загружает одну HTML-страницу один раз, а затем динамически обновляет содержимое без перезагрузки страницы.
Как работает:
- При первом запросе сервер отдаёт один
index.html+ бандл JS (и CSS) - Все переходы между «страницами» управляются JS в браузере (client-side routing)
- Данные подгружаются через AJAX/fetch в виде JSON, без HTML с сервера
- URL обновляется через History API (
pushState)
Что передаётся с сервера:
- Первый запрос:
index.html,bundle.js,styles.css - Последующие запросы: только JSON-данные через API (REST / GraphQL)
Плюсы: быстрые переходы, десктоп-подобный UX
Минусы: плохой SEO «из коробки», долгая первая загрузка (TTI), весь JS грузится сразу
Как браузер использует кэш при загрузке страницы?
Типы кэширования:
- Memory cache — самый быстрый, живёт до закрытия вкладки.
- Disk cache — файлы сохраняются на диске.
- Service Worker cache — программируемый кэш через Cache API.
Управление через HTTP-заголовки:
Cache-Control: max-age=31536000— кэшировать на год.ETag— сервер может вернуть 304 Not Modified, если ресурс не изменился.Last-Modified— аналогично, по дате изменения.
Что такое WebAssembly (WASM)?
WebAssembly (WASM) — бинарный формат исполняемого кода для браузера, результат компиляции с C/C++/Rust и других языков.
Ключевые факты:
- Работает почти с нативной скоростью
- Выполняется в изолированной песочнице
- Может взаимодействовать с JS через API
- Поддерживается во всех современных браузерах
- Figma, AutoCAD Web, Google Earth — используют WASM
Связь с SharedArrayBuffer: для многопоточного WASM используют SharedArrayBuffer + Atomics — разделяемая память между потоками. Требует заголовков на сервере:
Cross-Origin-Opener-Policy: same-origin
Cross-Origin-Embedder-Policy: require-corp
MutationObserver и IntersectionObserver
MutationObserver
Отслеживает изменения в DOM: добавление/удаление узлов, изменение атрибутов, изменение текста.
const observer = new MutationObserver((mutations) => {
mutations.forEach(m => console.log(m.type, m.target));
});
observer.observe(element, {
attributes: true, // изменение атрибутов (в т.ч. style, class)
childList: true, // добавление/удаление детей
subtree: true, // включать всех потомков
characterData: true // изменение текстовых узлов
});Можно ли отслеживать изменение стилей?
- ✅ Да, если стиль меняется через
element.style.color = 'red'— это меняет атрибутstyle, и{ attributes: true }это поймает - ✅ Да, если меняется класс —
{ attributes: true }поймает изменение атрибутаclass - ❌ Нет, если нужны вычисленные стили (
getComputedStyle) — MutationObserver их не отслеживает. CSS-переменные, медиа-запросы, анимации — за ними так не следить
IntersectionObserver
Отслеживает попадание элемента в область видимости (viewport или другой контейнер).
const observer = new IntersectionObserver((entries) => {
entries.forEach(entry => {
if (entry.isIntersecting) {
entry.target.src = entry.target.dataset.src; // lazy load
}
});
}, { threshold: 0.5 }); // 50% элемента должно быть видно
observer.observe(img);Применение: lazy loading, infinite scroll, анимации при скролле, трекинг показов.
| MutationObserver | IntersectionObserver | |
|---|---|---|
| Что отслеживает | Изменения DOM (структура, атрибуты) | Видимость элемента в viewport |
| Применение | Реакция на DOM-изменения | Lazy load, scroll-анимации |
См. также
- rendering-performance — диагностика тормозов, Web Vitals