Из каких этапов состоит отрисовка
Комментарии (1)
Ответ сгенерирован нейросетью и может содержать ошибки
Этапы отрисовки в браузере (Rendering Pipeline)
Отрисовка (rendering) — это процесс, при котором браузер преобразует HTML, CSS и JavaScript в пиксели на экране. Понимание этого процесса критически важно для оптимизации производительности и создания плавных интерфейсов.
1. Parsing (Парсинг)
Первый этап — браузер читает и парсит HTML документ:
// Во время парсинга HTML браузер:
// 1. Создаёт DOM (Document Object Model) дерево
// 2. Парсит CSS и создаёт CSSOM (CSS Object Model)
// 3. Встречает <script> — парсинг останавливается, выполняется JS
// Проблема: блокирующие скрипты
<script src="large.js"></script> <!-- парсинг ждёт выполнения -->
// Решение: асинхронная загрузка
<script async src="large.js"></script> <!-- параллельная загрузка -->
<script defer src="large.js"></script> <!-- выполнится после парсинга -->
Порядок выполнения:
<link rel="stylesheet">— загружается асинхронно, блокирует рендеринг<script async>— загружается параллельно, выполняется при готовности<script defer>— загружается параллельно, выполняется после парсинга DOM<script>(без атрибутов) — блокирует парсинг HTML
2. Style Recalculation (Пересчёт стилей)
Браузер объединяет DOM и CSSOM, вычисляя финальные стили для каждого элемента:
// CSS Specificity влияет на производительность
// Избегай глубоких селекторов
// Плохо: .container div.header span.title a { ... }
// Хорошо: .title { ... }
// Браузер считает стили справа налево!
const element = document.getElementById("myElement");
element.style.color = "red"; // Запускает recalculation
Что запускает пересчёт стилей:
- Изменение класса:
element.classList.add("active") - Изменение инлайн-стиля:
element.style.color = "red" - Изменение содержимого:
element.textContent = "new"
3. Layout (Макетирование)
Браузер вычисляет размеры и позиции всех элементов:
// Layout зависит от стилей
const width = element.offsetWidth; // Запускает layout!
const height = element.offsetHeight;
const top = element.offsetTop;
// Проблема: Forced Synchronous Layout
for (let i = 0; i < 1000; i++) {
element.style.width = (element.offsetWidth + 1) + "px";
// Каждой итерации: layout -> style change -> layout
// Очень медленно!
}
// Решение: batch читаемые операции, потом все записи
let widths = [];
for (let i = 0; i < 1000; i++) {
widths.push(element.offsetWidth); // Все reads вместе
}
for (let i = 0; i < 1000; i++) {
element.style.width = (widths[i] + 1) + "px"; // Все writes вместе
}
Что запускает Layout:
- Чтение размеров:
offsetWidth,offsetHeight,scrollTop,getBoundingClientRect() - Изменение размеров:
width,height,margin,padding - Изменение позиции:
top,left,position
4. Paint (Рисование)
Браузер рисует пиксели: текст, цвета, границы, тени и т.д.:
/* Paint-heavy свойства */
text-shadow: 0 0 10px rgba(0, 0, 0, 0.5); /* дорого */
box-shadow: 0 0 10px rgba(0, 0, 0, 0.5); /* дорого */
filter: blur(10px); /* дорого */
border-radius: 50%; /* дешево, но зависит от браузера */
/* Paint-cheap */
color: red; /* дёшево */
background: blue; /* дёшево */
Оптимизация Paint:
// Плохо: может запустить paint без необходимости
element.style.opacity = 0.5; // Все пиксели перерисовываются
// Хорошо: если используешь opacity для анимации
const animation = () => {
element.style.opacity = value;
requestAnimationFrame(animation);
};
5. Composite (Композиция)
Браузер объединяет слои (layers) в финальное изображение:
/* Создание новых слоёв улучшает производительность */
.fast-animation {
will-change: transform;
transform: translateZ(0); /* GPU acceleration */
animation: slide 0.5s ease-out;
}
@keyframes slide {
from { transform: translateX(0); }
to { transform: translateX(100px); }
}
/* Transform и opacity НЕ запускают layout/paint */
const animate = () => {
element.style.transform = "translateY(" + distance + "px)";
requestAnimationFrame(animate);
};
6. Display (Отображение)
Финальное изображение выводится на экран с частотой экрана (обычно 60 FPS = 16.67ms на кадр).
Полный цикл отрисовки
ParseHTML
|
v
Create DOM + CSSOM
|
v
Recalculate Styles
|
v
Layout (Reflow)
|
v
Paint (Repaint)
|
v
Composite
|
v
Display (16.67ms для 60 FPS)
Оптимизация производительности
requestAnimationFrame (RAP) — выполняется перед отрисовкой:
function animate() {
element.style.transform = "rotate(" + angle + "deg)";
angle += 1;
requestAnimationFrame(animate);
}
animate();
Приоритет операций:
-
Самые быстрые (GPU-accelerated):
transformopacitywill-change
-
Среднее (могут запустить paint):
background-colorcolorborder
-
Самые дорогие (запускают layout):
- Изменение размеров
- Изменение позиции
display,visibility
Инструменты для анализа:
- Chrome DevTools → Performance tab
- Профилировка: Frame time, FPS meter, Paint timing
Понимание этих этапов отрисовки позволяет писать код, который работает со скоростью 60+ FPS, создавая гладкие и отзывчивые интерфейсы.