Комментарии (2)
Ответ сгенерирован нейросетью и может содержать ошибки
Ориентировочное количество репаинтов за кадр
Вопрос «сколько будет repaint в один кадр?» не имеет фиксированного числового ответа, так как количество репаинтов (перерисовок) в течение одного кадра анимации (frame) зависит от множества факторов. В идеальном сценарии современного браузера, стремящегося к высокой производительности и плавности анимаций (60 FPS), целью является НОЛЬ репаинтов на кадр.
Почему ноль — это цель?
Процесс визуального обновления страницы в браузере (рендеринг), часто описываемый конвейером Pixel Pipeline или Rendering Pipeline, состоит из нескольких этапов:
- JavaScript → 2. Style Calculation (Recalc Style) → 3. Layout (Reflow) → 4. Paint (Repaint) → 5. Composite.
- Layout (Перекомпоновка/Reflow): Браузер вычисляет геометрию: размеры и положение каждого элемента. Изменение свойства, влияющего на геометрию (например,
width,height,margin,left), запускает этот затратный этап. - Paint (Отрисовка/Repaint): Браузер заполняет пиксели: рисует текст, цвета, изображения, тени и т.д. в памяти (в растре). Изменение визуальных свойств, не влияющих на макет (например,
color,background-color,visibility,box-shadow), обычно пропускает Layout, но запускает Paint.<!-- Пример кода, вызывающего repaint (и, возможно, reflow) --> <style> .box { width: 100px; height: 100px; background: red; transition: background 0.3s; } .box:hover { background: blue; /* Только repaint, layout не нужен */ /* width: 150px; */ /* Если раскомментировать, добавится и reflow */ } </style> <div class="box"></div> - Composite (Композитинг): Браузер собирает слои (layers) в конечное изображение на экране. Работает с GPU. Изменение свойств, которые обрабатываются композитором (например,
transform,opacity), часто позволяет пропустить и Layout, и Paint.
Идеальный кадр происходит, когда изменения затрагивают только этап Composite. Анимация через transform и opacity позволяет браузеру использовать GPU и готовые текстуры слоев, избегая repaint.
Когда repaint происходит в кадре?
- Начальный кадр или при первом изменении: При изменении свойства, требующего перерисовки, браузер выполнит repaint для соответствующих областей. Этот repaint происходит внутри данного цикла рендеринга, в рамках отведенных ~16.6 мс (для 60 FPS).
- Последующие кадры:
* **Худший сценарий**: Если свойство, требующее **repaint** (например, `background-color`), анимируется в цикле `requestAnimationFrame` или через CSS Transitions, то **repaint будет происходить на каждом кадре анимации**. Это большая нагрузка.
```javascript
// ПЛОХО: Вызывает repaint каждый кадр
function animateColor() {
const element = document.getElementById('box');
let hue = 0;
function update() {
hue = (hue + 1) % 360;
element.style.backgroundColor = `hsl(${hue}, 100%, 50%)`; // Вызовет repaint
requestAnimationFrame(update);
}
update();
}
```
* **Оптимальный сценарий**: Если анимируется только `transform`/`opacity`, то после первого **paint** браузер создает отдельный слой для элемента. В последующих кадрах происходит только **composite**, без нового **repaint**.
```javascript
// ХОРОШО: Скорее всего, вызовет только composite после создания слоя
function animateTransform() {
const element = document.getElementById('box');
let pos = 0;
function update() {
pos = (pos + 1) % 300;
element.style.transform = `translateX(${pos}px)`; // Вызовет composite
requestAnimationFrame(update);
}
update();
}
```
Факторы, влияющие на количество и стоимость repaint
- Размер области перерисовки (Paint Area): Перерисовка всего окна браузера (full repaint) — катастрофа для производительности. Локальный repaint маленького элемента — намного дешевле. Инструменты DevTools (Performance panel, Rendering > Paint flashing) помогают визуализировать области repaint.
- Сложность стилей элемента: Рисование сложных
box-shadow,border-radius, градиентов дороже, чем сплошного цвета. - Количество перерисовываемых элементов: Одновременное изменение 100 элементов вызовет больше работы, чем изменение одного.
- Наличие слоев (Layers): Браузер может поместить элемент на отдельный слой (например, при использовании
will-change: transformили 3D-трансформаций). Это изолирует repaint этого элемента, но создание и управление чрезмерным количеством слоев также имеет overhead.
Практический вывод для разработчика
- Стремитесь к нулю репаинтов в анимациях. Для этого анимируйте только
transformиopacity. Эти свойства оптимизированы для работы композитора. - Избегайте триггеров репаинта в часто выполняемом коде (внутри
requestAnimationFrame,scroll,resizeитерациях). - Используйте DevTools для профилирования:
* Включите `Rendering > Paint flashing`.
* Запишите **Performance Trace** и ищите длинные зеленые полосы **Paint** или красные полосы **Layout**.
Итог: В идеально оптимизированной анимации количество repaint за кадр равно 0. В реальности, при изменении свойств, влияющих на внешний вид (но не геометрию), может происходить 1 или более repaint на кадр (по одному для каждой области/слоя), что является узким местом для производительности. Ключевой навык — минимизировать эти случаи и управлять ими.