Performance CSS: минимизация repaint/reflow, оптимизация рендера

Почему браузер «тормозит»? Разбираем repaint и reflow

Браузер — не волшебник, а сложный механизм. Каждое изменение CSS заставляет его пересчитывать layout (reflow) или перерисовывать элементы (repaint). Чем чаще это происходит, тем медленнее работает страница.

Разница между reflow и repaint:

  • Reflow (он же layout) — перерасчёт геометрии элементов. Например, изменили width, margin или добавили DOM-узел.
  • Repaint — визуальное обновление без изменения layout. Пример: color, background, visibility.

💡 Как запомнить? Reflow = «где?» (позиция, размер), Repaint = «как?» (цвет, тень).


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

1. Группируйте изменения DOM

Каждое добавление/удаление элемента вызывает reflow. Вместо этого:

// Плохо: 10 reflow!
for (let i = 0; i < 10; i++) {
  document.body.appendChild(document.createElement('div'));
}

// Хорошо: 1 reflow!
const fragment = document.createDocumentFragment();
for (let i = 0; i < 10; i++) {
  fragment.appendChild(document.createElement('div'));
}
document.body.appendChild(fragment);

2. Избегайте «чтения» геометрии после «записи»

Браузер оптимизирует reflow, но только если вы не заставляете его возвращать актуальные значения. Пример:

// Плохо: вызывает принудительный reflow!
element.style.width = '100px';
const width = element.offsetWidth; // Чтение → браузер вынужден обновить layout
element.style.height = `${width}px`;

// Хорошо: сначала читаем, потом пишем
const width = element.offsetWidth;
element.style.width = '100px';
element.style.height = `${width}px`;

Оптимизируем repaint

1. Используйте transform и opacity

Эти свойства не вызывают reflow и обрабатываются отдельным слоем (composite). Анимация их через transition или animation — идеально!

.box {
  transition: transform 0.3s ease; /* GPU-ускорение! */
}
.box:hover {
  transform: scale(1.1); /* Никакого repaint! */
}

2. Осторожно с will-change

Подсказка браузеру о будущих изменениях:

.element {
  will-change: transform; /* Готовимся к анимации */
}

⚠️ Не злоупотребляйте! Лишние слои (layers) съедают память.


CSS-свойства: от «тяжёлых» к «лёгким»

Тяжёлые (reflow) Средние (repaint) Лёгкие (composite)
width color transform
margin background opacity
padding box-shadow filter
position outline clip-path

Практика: оптимизация анимаций

Проблема: Анимация top/left вызывает reflow на каждом кадре.
Решение: Заменяем на transform: translate().

/* Плохо: прыгающий reflow */
@keyframes slide {
  from { left: 0; }
  to { left: 100px; }
}

/* Хорошо: плавно и без reflow */
@keyframes slide {
  from { transform: translateX(0); }
  to { transform: translateX(100px); }
}

Итоги: чеклист оптимизации

  1. DOM: Изменяйте группами, используйте DocumentFragment.
  2. JavaScript: Читайте геометрию (например, offsetHeight) перед записью.
  3. Анимации: transform и opacity — ваши лучшие друзья.
  4. Слои: will-change — только там, где действительно нужно.
  5. Инструменты: Chrome DevTools → Performance → ищите «Layout Thrashing».

Теперь ваш CSS не просто красивый — он молниеносный! ⚡

Скрыть рекламу навсегда

📘 VK Видео — обучение без ограничений

Все уроки доступны без VPN, без блокировок и зависаний.

Можно смотреть с телефона, планшета или компьютера — в любое время.

▶️ Смотреть на VK Видео