Що таке "reflow" і "repaint"?
1. Що таке reflow і repaint
Коли ти змінюєш DOM або CSS у браузері, рушій рендерингу (у Chrome це Blink) повинен перерахувати, як сторінка виглядає. Ця робота ділиться на два етапи:
| Термін | Що робить | Коли відбувається |
|---|---|---|
| Reflow (layout) | Перерахунок геометрії елементів: розмірів, позицій, відступів, висоти, ширини тощо | Коли змінюється структура DOM або CSS, що впливають на розкладку (layout) |
| Repaint (paint) | Перемальовування видимих пікселів (кольори, фон, тіні, бордери тощо) без перерахунку геометрії | Коли змінюється лише зовнішній вигляд, а не розмір чи позиція |
2. Як це працює під капотом
Reflow -> браузер повинен:
- Перерахувати розміри і позиції елементів (layout tree).
- Визначити, які ділянки екрана потрібно перемалювати.
- Запустити Repaint (перемальовування).
Repaint -> браузер зафарбовує змінені пікселі (paint + composite).
Кожен
reflowмайже завжди спричиняєrepaint, але не коженrepaintпотребуєreflow.
3. Приклади Reflow
Reflow спричиняють:
- зміна розмірів (
width,height,padding,margin,border,font-size); - додавання / видалення DOM-елементів;
- зміна тексту;
- обчислення властивостей, що залежать від layout (
offsetWidth,clientHeight,getComputedStyle); - зміна класу, що впливає на позиціонування або розміри;
- зміна розміру вікна браузера (resize);
- прокрутка (scroll).
Приклад:
element.style.width = '400px'; // Reflow + Repaint4. Приклади Repaint
Repaint спричиняють:
- зміна кольору (
color,background-color); - зміна прозорості (
opacity); - тіні (
box-shadow); - outline;
- visibility (якщо елемент залишається на місці).
Приклад:
element.style.backgroundColor = 'red'; // Тільки Repaint5. Чому reflow небезпечний для продуктивності
Reflow - одна з найдорожчих операцій у браузері, особливо якщо вона зачіпає багато елементів.
Проблема:
- Layout-дерево пов'язане - зміна одного елемента може змусити перерахувати весь документ.
- Кожен reflow може займати десятки мілісекунд, особливо при складних layout-ах.
Якщо робити їх у циклі або часто - інтерфейс починає "лагати".
6. Типові помилки, що спричиняють зайвий reflow
| Помилка | Що відбувається |
|---|---|
| Багаторазова зміна стилю окремо | Щоразу тригериться новий reflow |
Звернення до offsetHeight після зміни стилю | Браузер змушений синхронно перерахувати layout |
| Зміна класів у циклі | Reflow на кожній ітерації |
Анімація властивостей, що впливають на layout (наприклад, width, top, margin) | Layout перераховується на кожному кадрі |
| Часте додавання DOM-елементів | Кожен insert спричиняє перерахунок дерева |
7. Як зменшити кількість reflow / repaint
| Підхід | Що робить |
|---|---|
| Batch updates | Змінюй кілька властивостей за раз (через classList або cssText) |
| DocumentFragment | Додавай DOM-елементи поза документом, потім вставляй усе одразу |
| Кешуй обчислення | const height = el.offsetHeight; перед циклом |
| Уникай явно layout-залежних стилів | Не анімуй width, height, top, left |
| Використовуй CSS transform і opacity | GPU-анімації не спричиняють reflow |
| requestAnimationFrame() | Для анімацій замість setInterval |
| will-change | Заздалегідь повідомляє браузеру, які властивості будуть змінюватися (для оптимізації) |
8. Приклад поганого коду (багато reflow)
for (let i = 0; i < 100; i++) {
const el = document.createElement('div');
document.body.appendChild(el); // Reflow щоразу
el.style.width = i + 'px'; // Reflow
console.log(el.offsetHeight); // Forced reflow
}Оптимізована версія:
const fragment = document.createDocumentFragment();
for (let i = 0; i < 100; i++) {
const el = document.createElement('div');
el.style.width = i + 'px';
fragment.appendChild(el);
}
document.body.appendChild(fragment); // 1 Reflow9. Взаємозв'язок з event loop і FPS
Reflow/Repaint відбуваються у фазі рендерингу кадру (frame rendering) - між макро- і мікрозавданнями event loop.
Для плавної анімації потрібно вкладатися в 16.6 мс (60 FPS). Якщо layout займає більше - кадри пропускаються -> "фризи".
10. Коротке резюме
| Термін | Що робить | Приклад | Вплив |
|---|---|---|---|
| Reflow (layout) | Перерахунок геометрії і позицій | зміна width, margin, додавання DOM | дорога операція |
| Repaint (paint) | Перемальовування зовнішнього вигляду | зміна color, background, opacity | помірно затратна |
| Composite | Склеювання шарів після paint | transform, opacity | дешева (GPU) |
| Мета | Мінімізувати Reflow, анімувати тільки transform і opacity | - | максимум FPS |
Коротка відповідь
Для співбесідиКоротка відповідь допоможе вам впевнено відповідати на цю тему під час співбесіди.