В какой момент происходит рендеринг
Комментарии (1)
Ответ сгенерирован нейросетью и может содержать ошибки
Рендеринг веб-страницы: полная хронология
Рендеринг — это процесс преобразования HTML, CSS и JavaScript в пиксели на экране. Это не один момент, а серия этапов, которые браузер выполняет в строгом порядке. Понимание этой хронологии критично для оптимизации производительности.
Основная схема рендеринга
1. Parsing (разбор)
↓
2. Style Calculation (расчёт стилей)
↓
3. Layout (расчёт позиций и размеров)
↓
4. Paint (рисование пиксели)
↓
5. Composite (комбинирование слоёв)
Этап 1: Parsing (разбор HTML/CSS/JS)
Когда: Сразу после получения байтов с сервера
Браузер строит:
- DOM (Document Object Model) — из HTML
- CSSOM (CSS Object Model) — из CSS
- Обнаруживает блокирующие ресурсы (скрипты)
// Скрипт БЛОКИРУЕТ разбор HTML
<script src="heavy.js"></script>
<div>Эта div будет отрисована только после загрузки скрипта</div>
// Решение: async/defer
<script src="heavy.js" defer></script> // Загружается параллельно, выполняется после
<script src="analytics.js" async></script> // Загружается параллельно, выполняется сразу
Этап 2: Style Calculation
Когда: После построения CSSOM, браузер рассчитывает финальные стили для каждого элемента
Это включает:
- Каскадирование CSS (какой стиль победит)
- Наследование свойств
- Специфичность селекторов
/* Тяжелые селекторы замедляют Style Calculation */
body > div > p > span { color: red; } /* O(n^2) */
/* Быстрые селекторы */
.text { color: red; } /* O(1) */
Этап 3: Layout (Reflow)
Когда: Браузер рассчитывает позицию и размер каждого элемента
Это самый дорогой этап. Операции, которые триггерят новый Layout:
// Плохо: 3 reflow
const box = document.getElementById("box");
box.style.width = "100px"; // reflow 1
const width = box.offsetWidth; // reflow 2 (чтение вынуждает layout)
box.style.height = "50px"; // reflow 3
// Хорошо: 1 reflow
const box = document.getElementById("box");
const width = box.offsetWidth; // Сначала читаем всё
box.style.width = "100px";
box.style.height = "50px"; // Записи батчатся, 1 reflow
Операции, которые триггерят Layout:
- Изменение width/height
- Изменение position/top/left
- Добавление/удаление DOM элементов
- Чтение offsetHeight, clientWidth, scrollTop
- Изменение font-size
Этап 4: Paint (Raster)
Когда: Браузер рисует содержимое элементов на слоях
Это быстрее, чем Layout, но всё равно дорого. Paint триггерится при:
- Изменении цветов (background, border, text color)
- Изменении opacity
- Изменении box-shadow
// Плохо: Paint каждый раз
box.style.backgroundColor = "red"; // Paint
box.style.boxShadow = "0 0 10px black"; // Paint
// Хорошо: используй GPU-ускорение (no Paint)
box.style.transform = "translateX(10px)"; // Только Composite
box.style.opacity = "0.5"; // С will-change может избежать Paint
Этап 5: Composite
Когда: Браузер комбинирует слои (layers) в финальное изображение
Это самый быстрый этап, потому что использует GPU:
/* Создаёт отдельный слой (composition layer) */
.animated {
transform: translate3d(0, 0, 0);
will-change: transform;
}
/* Не создаёт слой, требует Paint */
.bad-animation {
left: 0;
}
Связь с JavaScript
CSSOM-Tree Blocking: CSS блокирует выполнение JavaScript:
<head>
<link rel="stylesheet" href="style.css">
</head>
<body>
<script>
// Этот скрипт НЕ выполнится, пока style.css не загружен
</script>
</body>
Оптимизация рендеринга
1. Critical Rendering Path (CRP):
<link rel="preload" as="font" href="Inter.woff2" crossorigin>
<link rel="preload" as="style" href="critical.css">
2. Минимизируй Layout Thrashing:
requestAnimationFrame(() => {
document.getElementById("box").style.width = "100px";
});
3. Используй CSS containment:
.card {
contain: layout style paint;
}
Core Web Vitals и рендеринг
- LCP (Largest Contentful Paint): Когда самый большой контент отрисован
- FID (First Input Delay): Задержка перед выполнением JS после клика
- CLS (Cumulative Layout Shift): Неожиданные сдвиги элементов
Вывод
Рендеринг — это 5 последовательных этапов:
- Parsing — быстро
- Style Calculation — умеренно
- Layout — дорого
- Paint — дорого
- Composite — быстро (GPU)
Для максимальной производительности избегай Layout Thrashing и используй GPU-ускорение через transform и will-change.