← Назад к вопросам

Что такое CSS Repaint?

2.3 Middle🔥 202 комментариев
#HTML и CSS

Комментарии (2)

🐱
deepseek-v3.2PrepBro AI6 апр. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Что такое CSS Repaint (Перерисовка)?

CSS Repaint (или перерисовка) — это процесс визуального обновления элементов веб-страницы, при котором браузер перерисовывает (перезаполняет) пиксели на экране без изменения их геометрии (размера или положения). Это происходит, когда изменяются стили элемента, не влияющие на его расположение в потоке документа или размеры соседних элементов.

Механизм работы в контексте рендеринга браузера

Чтобы понять repaint, нужно рассмотреть конвейер рендеринга браузера:

  1. Стилизация (Recalculate Style) — Браузер вычисляет, какие CSS-правила применяются к каждому элементу.
  2. Макет (Layout/Reflow) — Рассчитывает геометрию: размеры, положение элементов.
  3. Отрисовка (Paint) — Заполнение пикселей: текст, цвета, тени, изображения.
  4. Композитинг (Composite) — Слои объединяются в финальное изображение.

Repaint происходит на этапе Paint. Если изменения касаются только внешнего вида, но не макета (например, цвет, фон, видимость, outline), браузер может пропустить затратный этап Layout и сразу выполнить Repaint и Composite.

Примеры свойств, вызывающих Repaint:

  • color, background-color, border-color
  • visibility, opacity (при определённых условиях)
  • box-shadow, text-shadow
  • background-image (изменение изображения)
  • outline, outline-color
/* Изменение этих свойств вызовет repaint, но обычно не reflow */
.button:hover {
  color: #ff0000;           /* Repaint */
  background-color: #f0f0f0; /* Repaint */
  box-shadow: 2px 2px 5px rgba(0,0,0,0.3); /* Repaint */
}

Repaint vs Reflow (Перекомпоновка)

Ключевое отличие — влияние на производительность:

  • Reflow (Layout)Более дорогой процесс, так как браузер должен пересчитать положение и размеры элемента и, возможно, соседних элементов, что может вызвать каскадные изменения по всему дереву. Вызывается изменениями геометрии: ширины, высоты, шрифтов, отступов и т.д.
  • RepaintОтносительно менее затратен, так как не трогает геометрию. Однако при частых или масштабных repaint'ах (например, анимация box-shadow на большом элементе) производительность также серьёзно страдает.
// ПРИМЕР: Сравнение действий
const element = document.getElementById('myDiv');

// Вызовет и Reflow, и Repaint (изменение ширины = изменение макета)
element.style.width = '500px';

// Вызовет, скорее всего, только Repaint (цвет не влияет на геометрию)
element.style.color = 'blue';

Почему Repaint важен для производительности?

Даже без reflow, частые или сложные repaint'ы создают нагрузку:

  1. Область перерисовки (Paint Area) — Браузер определяет, какие области экрана нужно обновить. Сложные страницы могут привести к перерисовке всего viewport.
  2. Сложность слоя (Layer Complexity) — Элементы с border-radius, box-shadow, градиентами требуют больше вычислений для отрисовки.
  3. Анимация и интерактивность — Неоптимизированные анимации (например, на margin-left вместо transform) заставляют страницу постоянно перерисовываться, что приводит к "дрожанию" (jank) и низкому FPS.

Как оптимизировать и минимизировать Repaint?

1. Используйте свойства, управляемые композитором (Compositor-Only Properties)

Для анимаций применяйте свойства, которые обрабатываются на этапе Composite, минуя и Layout, и Paint. Это самый эффективный способ.

/* ХОРОШО: Анимация с помощью transform и opacity */
.optimized {
  animation: slide 2s infinite;
}
@keyframes slide {
  from { transform: translateX(0); opacity: 0.5; }
  to { transform: translateX(100px); opacity: 1; }
}

/* ПЛОХО: Анимация, вызывающая repaint/reflow */
.unoptimized {
  animation: bad-slide 2s infinite;
}
@keyframes bad-slide {
  from { margin-left: 0; }
  to { margin-left: 100px; }
}

2. Снижайте область перерисовки

  • Изолируйте изменяющиеся элементы с помощью overflow: hidden или contain: paint.
  • Старайтесь, чтобы изменения затрагивали минимальную часть экрана.

3. Правильно используйте will-change

Сообщите браузеру о предстоящих изменениях, чтобы он мог подготовить слой.

.element-about-to-animate {
  will-change: transform, opacity;
}

Используйте экономно, только для элементов, которые действительно будут меняться.

4. Избегайте вложенных селекторов для часто изменяемых элементов

Слишком сложные селекторы могут увеличить время на этапе Recalculate Style, что предшествует repaint.

/* Менее эффективно для частых изменений */
div.container ul.list > li.item a.link:hover { ... }

/* Более эффективно (если возможно) */
.optimized-link:hover { ... }

5. Работайте с видимостью

Для скрытия/показа используйте opacity: 0 или visibility: hidden вместо display: none, если элемент будет часто появляться. Первые два могут сохранить слой и избежать полного reflow при повторном показе.

Инструменты для анализа Repaint

В Chrome DevTools:

  1. Откройте Performance панель.
  2. Запишите профиль производительности.
  3. На временной шкале ищите блоки Rendering.
  4. Включите "Paint flashing" (в Rendering инструментах). Браузер подсветит зелёным области, которые перерисовываются при взаимодействии.

Заключение

CSS Repaint — критически важное понятие для создания плавных и отзывчивых интерфейсов. Хотя оно менее затратно, чем Reflow, его неконтролируемое использование, особенно в анимациях и частых визуальных обновлениях, является частой причиной низкой производительности фронтенда. Современная стратегия оптимизации сводится к сведению к минимуму работы основного потока за счёт использования свойств, анимируемых композитором (transform, opacity), и грамотного управления слоями, что позволяет браузеру выполнять обновления максимально эффективно, поддерживая высокий FPS.