1. От URL до первого байта: DNS, TCP/TLS, HTTP, кеши и Service Worker
Подготовка к собеседованию в Яндекс: Browser Pipeline, Promises и Генераторы
На технических интервью в крупные компании (как Яндекс, Avito, Тинькофф) требуют глубокого понимания того, как работает платформа. Вас спросят не только о том, как написать код, но и о том, какой ценой он выполняется. В этой статье мы разберем полный путь работы браузера, механизмы рендеринга и внутреннее устройство асинхронности в JavaScript.
Часть 1. Browser Pipeline: От URL до пикселей
Этот процесс делится на два больших этапа: сетевой (доставка ресурсов) и рендеринг (превращение кода в картинку).
!Временная шкала от ввода URL до получения первого байта
1. Сетевой этап (Network)
Когда пользователь вводит URL и нажимает Enter, браузер выполняет следующие шаги:
SYN → SYN-ACK → ACK для создания надежного канала.
* TLS Handshake: Обмен сертификатами и ключами шифрования. В TLS 1.3 это происходит быстрее (1 RTT), но это все равно затратная операция.
2. Построение объектных моделей (Parsing)
Как только браузер получает первые байты HTML, он начинает парсинг, не дожидаясь загрузки всего документа.
<script>, он блокирует построение DOM (если нет атрибутов async или defer), загружает и выполняет JS.
!Создай фото правил в веб разработке
3. Render Tree
Браузер объединяет DOM и CSSOM в Render Tree (дерево рендеринга). В него попадают только видимые элементы.
* Элементы с display: none не попадают в Render Tree.
* Элементы с visibility: hidden попадают (они занимают место, просто прозрачные).
* Псевдоэлементы (::before, ::after) добавляются сюда.
4. Layout (Reflow) — Компоновка
На этом этапе браузер рассчитывает геометрию каждого элемента: точные координаты () и размеры () в пикселях экрана. Процесс идет рекурсивно от <html> вглубь.
Понятие Reflow (перекомпоновка) означает повторный запуск этого процесса при изменениях.
5. Paint (Repaint) — Отрисовка
Браузер заполняет пиксели: цвета, фоны, тени, границы, текст. Отрисовка часто происходит на нескольких слоях.
Понятие Repaint (перерисовка) означает обновление внешнего вида без изменения геометрии.
6. Composite — Композиция
Финальный этап. Браузер собирает все слои в итоговое изображение на экране. Этот этап выполняется на GPU (видеокарте), что делает его очень быстрым.
Часть 2. Reflow, Repaint и Composite: Детальный разбор
Понимание этих терминов критично для оптимизации производительности (60 FPS).
Reflow (Layout)
Самая дорогая операция. Происходит, когда меняется геометрия страницы или структура дерева.
Что вызывает Reflow:
* Добавление/удаление DOM-узлов.
* Изменение размеров окна браузера (resize).
* Изменение шрифта.
* Изменение свойств: width, height, padding, margin, border, left, top.
* Чтение геометрических свойств (Forced Synchronous Layout). Если вы меняете стиль, а потом сразу читаете offsetWidth, браузер обязан прервать JS и срочно пересчитать макет, чтобы дать актуальные данные.
Repaint
Средняя по стоимости операция. Происходит, когда меняется внешний вид, но не геометрия.
Что вызывает Repaint:
* color, background-color.
* visibility.
* box-shadow, outline.
Composite
Самая дешевая операция. Если свойство можно обработать только на этапе композиции, Layout и Paint пропускаются.
Свойства для Composite (GPU):
* transform (перемещение, масштабирование, вращение).
* opacity (прозрачность).
* filter (некоторые фильтры).
> Для плавных анимаций всегда используйте transform и opacity. Изменение left/top вызывает Reflow каждый кадр, что нагружает CPU.
Часть 3. Promises (Промисы)
Промис — это объект, представляющий результат асинхронной операции, который будет получен в будущем. Это замена callback-hell.
Внутреннее устройство
У промиса есть три состояния:
value).reason).Смена состояния необратима. Из Fulfilled нельзя перейти в Rejected и наоборот.
Microtask Queue
Обработчики .then(), .catch(), .finally() выполняются асинхронно через Microtask Queue. Микрозадачи имеют приоритет перед макрозадачами (setTimeout, I/O) и выполняются сразу после текущего синхронного кода, но до рендеринга.
Пример порядка выполнения:
Ключевые методы
* Promise.all([p1, p2]) — ждет выполнения всех. Если хоть один упал — падает весь all.
* Promise.allSettled([p1, p2]) — ждет завершения всех (неважно, успех или ошибка). Возвращает массив статусов.
* Promise.race([p1, p2]) — возвращает результат первого завершившегося (успех или ошибка).
* Promise.any([p1, p2]) — возвращает первый успешный. Ошибка будет только если все упали.
Часть 4. Генераторы (Generators)
Генераторы — это функции, выполнение которых можно приостанавливать и возобновлять. Они лежат в основе async/await и библиотек вроде Redux-Saga.
Синтаксис и работа
Обозначаются звездочкой function*. При вызове код функции не выполняется сразу, а возвращается объект итератора.
Ключевое слово yield
yield делает две вещи:
return).Двусторонний обмен данными
В генератор можно передавать данные через next(value). Значение попадет в переменную слева от yield, на котором стояла пауза.
Это позволяет писать асинхронный код в синхронном стиле, что и реализовано в синтаксическом сахаре async/await (где await — это автоматический yield промиса).
Итоги
transform и opacity, так как они вызывают только Composite и обрабатываются на GPU.all, race, allSettled, any.yield). Позволяют создавать итераторы и управлять потоком выполнения, являясь фундаментом для async/await.