Критический путь отрисовки
Вопрос
Что браузер делает с HTML и CSS до первого кадра, и чем reflow отличается от repaint?
Короткий ответ
Браузер качает HTML, строит DOM, встречает CSS и JS. Стили без media, который сразу ложен, блокируют первую отрисовку: нужен CSSOM. Обычный скрипт без async и defer останавливает разбор HTML, пока файл не скачается и не выполнится. defer качается параллельно и выполняется после разбора документа, по порядку тегов. async выполнится, как только скачается, порядок между такими скриптами не гарантирован.
Дальше дерево рендера, раскладка (layout, reflow) и отрисовка (paint). Смена геометрии — ширина, шрифт, вставка узла — запускает layout. Смена цвета часто ограничивается paint. transform и opacity чаще не трогают layout и могут остаться на слое композитора.
Чтение offsetHeight сразу после записи стиля заставляет браузер посчитать layout синхронно. Чередование чтений и записей в цикле называется layout thrashing.
Разбор
Критический путь — ресурсы, без которых нельзя показать первый экран: HTML, блокирующий CSS, блокирующий JS. Картинка ниже сгиба и отложенный скрипт аналитики в него не входят.
document готов по DOMContentLoaded, когда разобран HTML и выполнены defer. load ждёт ещё стили, картинки и фреймы.
Слой для анимации создают осознанно. Бесконечный will-change: transform на всём списке держит лишнюю память. Свойство ставят на время анимации или не ставят, если и так анимируется transform.
На что смотрят на senior
Метрики, которые называют вслух: LCP (крупный контент), INP (отзывчивость на ввод), CLS (сдвиги вёрстки). Картинка без размера и шрифт без запасного метрического начертания двигают макет. Длинная задача в JS дольше примерно 50 мс бьёт по INP, даже если кадры скролла гладкие.
Принудительный синхронный layout виден в Performance: фиолетовые пересчёты между чтением геометрии и сменой класса. Лечение — прочитать геометрию пачкой, потом записать стили пачкой.
Типичные ошибки
- Ставить скрипт в
headбезdeferи блокировать разбор. - Читать
offsetWidthвнутри цикла по сотне элементов. - Анимировать
topиleftтам, где хватаетtransform. - Путать первый кадр и
load: пользователь видит страницу раньше, чем сработалоload.
Задача
Скрипт подключён в head тремя способами по очереди: без атрибутов, с defer, с async. Какой из них точно выполнится до разбора всего HTML?
Показать ответ
Без атрибутов. Браузер останавливает парсер, пока скрипт не скачается и не выполнится.
defer выполняется после того, как документ разобран, сохраняя порядок таких скриптов. async выполнится сразу после загрузки и может попасть и до, и после конца HTML: порядок не гарантирован.