← Назад к вопросам
Что такое repaint?
2.0 Middle🔥 141 комментариев
#Браузер и сетевые технологии#Оптимизация и производительность
Комментарии (1)
🐱
claude-haiku-4.5PrepBro AI22 мар. 2026 г.(ред.)
Ответ сгенерирован нейросетью и может содержать ошибки
Что такое repaint?
Repaint (перерисовка) — это процесс, при котором браузер переносит пиксели на экран после изменения внешних свойств элемента (цвет, тень, видимость), не меняя его размеры и положение. Это критическое понимание для оптимизации производительности веб-приложений.
Различие: reflow vs repaint
Это два различных процесса, которые часто путают:
Reflow (перекомпоновка):
- Пересчёт макета (layout) документа
- Определение размеров и положения элементов
- Затрагивает DOM модель
- Более дорогой процесс
- Влечёт за собой repaint
// Операции, вызывающие reflow:
element.width = 100; // изменение размера
element.style.marginLeft = 10; // изменение позиции
element.offsetWidth; // чтение размера
window.innerWidth; // получение высоты окна
Repaint (перерисовка):
- Перерисовка внешнего вида элемента
- Не меняет макет (layout)
- Менее дорогой процесс
- Может происходить без reflow
// Операции, вызывающие repaint (без reflow):
element.style.color = 'red'; // цвет текста
element.style.backgroundColor = 'blue'; // цвет фона
element.style.opacity = 0.5; // прозрачность
element.style.boxShadow = '0 0 5px'; // тень
element.style.borderColor = 'red'; // цвет границы
Как браузер обновляет экран
1. JavaScript выполнение
2. Parsing (парсинг CSS, HTML)
3. Render Tree (дерево рендеринга)
4. Layout (reflow) — вычисление размеров/позиций
5. Paint (repaint) — отрисовка пикселей
6. Composite (композиция слоёв)
7. Отображение на экране
Практические примеры repaint
Пример 1: Простое изменение цвета (только repaint)
// ✅ Этот код вызывает только repaint (быстро)
const element = document.getElementById('box');
element.style.color = 'blue'; // repaint
element.style.backgroundColor = 'yellow'; // repaint
element.style.opacity = 0.8; // repaint
// ❌ Этот код вызывает reflow + repaint (медленнее)
element.style.width = '100px'; // reflow
element.style.height = '50px'; // reflow
element.style.color = 'red'; // repaint
Пример 2: Изменение видимости
// ✅ Только repaint (используется display в DOM)
element.style.display = 'none'; // reflow (переносит элемент)
element.style.visibility = 'hidden'; // repaint (скрывает, место занято)
element.style.opacity = '0'; // repaint (прозрачность)
Пример 3: Анимация (repaint vs reflow)
// ❌ Плохо — вызывает reflow при каждом шаге
function animateBadly() {
for (let i = 0; i < 100; i++) {
element.style.left = i + 'px'; // reflow + repaint
}
}
// ✅ Хорошо — только repaint
function animateWell() {
for (let i = 0; i < 100; i++) {
element.style.backgroundColor = `rgb(${i}, 0, 0)`; // repaint
}
}
// ✅ Лучше всего — используй CSS анимацию
// CSS анимация оптимизирована браузером
element.style.animation = 'moveRight 1s ease';
Операции, вызывающие repaint (но НЕ reflow)
const element = document.getElementById('box');
// Цвет и эффекты
element.style.color = 'blue';
element.style.backgroundColor = 'red';
element.style.borderColor = 'green';
// Прозрачность
element.style.opacity = 0.5;
// Тени (не меняют макет)
element.style.boxShadow = '0 10px 30px rgba(0,0,0,0.3)';
element.style.textShadow = '2px 2px 4px rgba(0,0,0,0.5)';
// Трансформации (используют GPU)
element.style.transform = 'scale(1.2)';
element.style.transform = 'rotate(45deg)';
// Фильтры
element.style.filter = 'blur(5px)';
Операции, вызывающие reflow (и, следовательно, repaint)
const element = document.getElementById('box');
// Размеры
element.style.width = '200px'; // reflow
element.style.height = '100px'; // reflow
element.style.padding = '10px'; // reflow
// Позиция
element.style.left = '50px'; // reflow
element.style.top = '100px'; // reflow
// Границы
element.style.borderWidth = '2px'; // reflow
// Чтение свойств (триггер reflow)
const width = element.offsetWidth; // reflow
const height = element.clientHeight; // reflow
const top = element.offsetTop; // reflow
Лучшие практики для оптимизации
1. Батчинг (группировка изменений)
// ❌ Плохо: множественные reflow
element.style.width = '100px'; // reflow
element.style.height = '50px'; // reflow
element.style.padding = '10px'; // reflow
// ✅ Хорошо: один reflow
element.style.cssText = 'width: 100px; height: 50px; padding: 10px;';
// ✅ Или используй класс
element.classList.add('my-style'); // один reflow
2. Избегай чтения и записи в перемешку
// ❌ Плохо: чередование чтения и записи
element.style.left = '50px'; // reflow
const left = element.offsetLeft; // reflow
element.style.top = '100px'; // reflow
const top = element.offsetTop; // reflow
// ✅ Хорошо: сначала читай, потом пиши
const left = element.offsetLeft; // reflow (один раз)
const top = element.offsetTop; // reflow (один раз)
element.style.left = left + 50 + 'px';
element.style.top = top + 100 + 'px';
3. Используй transform вместо top/left
// ❌ Вызывает reflow при каждом кадре
function animatePosition() {
let x = 0;
setInterval(() => {
x += 5;
element.style.left = x + 'px'; // reflow
}, 16);
}
// ✅ Только repaint (или даже GPU acceleration)
function animatePositionOptimized() {
let x = 0;
setInterval(() => {
x += 5;
element.style.transform = `translateX(${x}px)`; // repaint (быстрее)
}, 16);
}
4. Используй requestAnimationFrame
// ✅ Синхронизируется с refresh rate браузера
function animate() {
requestAnimationFrame(() => {
element.style.backgroundColor = 'blue'; // repaint
// или
element.style.transform = 'scale(1.1)'; // repaint
});
}
5. Дублируй элемент для сложных операций
// ❌ Множественные изменения = множественные reflow
for (let i = 0; i < 1000; i++) {
const item = document.createElement('div');
item.textContent = i;
parent.appendChild(item); // reflow для каждого элемента
}
// ✅ Один reflow для всех элементов
const fragment = document.createDocumentFragment();
for (let i = 0; i < 1000; i++) {
const item = document.createElement('div');
item.textContent = i;
fragment.appendChild(item); // в памяти, без reflow
}
parent.appendChild(fragment); // один reflow
Профилирование repaint
// Chrome DevTools Performance:
// 1. Откройте DevTools (F12)
// 2. Перейдите на вкладку Performance
// 3. Нажмите Record
// 4. Выполните операции
// 5. Нажмите Stop
// 6. Посмотрите на временную шкалу (Paint события)
// Или используй Performance API:
performance.mark('start');
element.style.color = 'red';
performance.mark('end');
performance.measure('paint', 'start', 'end');
Когда repaint неизбежен
// Некоторые изменения всегда требуют repaint:
// 1. Изменение фонового цвета
// 2. Изменение цвета текста
// 3. Изменение границ
// 4. Изменение теней
// 5. Изменение фильтров
// 6. Изменение видимости (display: none это reflow)
// Но это всё равно быстрее, чем reflow!
Вывод: понимание разницы между repaint и reflow критически важно для написания высокопроизводительного кода. Используй инструменты профилирования браузера для анализа и оптимизации своих приложений.