Запропонувати правкуПокращити цю статтюДопрацюйте відповідь до «Що таке "reflow" і "repaint"?». Ваші зміни проходять модерацію перед публікацією.Потрібне підтвердженняКонтентЩо ви змінюєте🇺🇸EN🇺🇦UAПереглядЗаголовок (UA)Коротка відповідь (UA)**Reflow** - це перерахунок геометрії елементів (розмірів, позицій, відступів), а **repaint** - перемальовування видимих пікселів без перерахунку геометрії. **Ключове:** reflow майже завжди спричиняє repaint, але не кожен repaint потребує reflow, і reflow - одна з найдорожчих операцій у браузері.Показується над повною відповіддю для швидкого нагадування.Відповідь (UA)Зображення## 1. Що таке reflow і repaint Коли ти змінюєш DOM або CSS у браузері, рушій рендерингу (у Chrome це Blink) повинен **перерахувати, як сторінка виглядає**. Ця робота ділиться на **два етапи:** | Термін | Що робить | Коли відбувається | |---|---|---| | **Reflow (layout)** | Перерахунок геометрії елементів: розмірів, позицій, відступів, висоти, ширини тощо | Коли змінюється структура DOM або CSS, що впливають на **розкладку (layout)** | | **Repaint (paint)** | Перемальовування видимих пікселів (кольори, фон, тіні, бордери тощо) без перерахунку геометрії | Коли змінюється лише **зовнішній вигляд**, а не розмір чи позиція | ## 2. Як це працює під капотом **Reflow** -> браузер повинен: 1. Перерахувати розміри і позиції елементів (layout tree). 2. Визначити, які ділянки екрана потрібно перемалювати. 3. Запустити **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). **Приклад:** ```javascript element.style.width = '400px'; // Reflow + Repaint ``` ## 4. Приклади Repaint ### Repaint спричиняють: - зміна кольору (`color`, `background-color`); - зміна прозорості (`opacity`); - тіні (`box-shadow`); - outline; - visibility (якщо елемент залишається на місці). **Приклад:** ```javascript element.style.backgroundColor = 'red'; // Тільки Repaint ``` ## 5. Чому 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) ```javascript 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 } ``` Оптимізована версія: ```javascript 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 Reflow ``` ## 9. Взаємозв'язок з 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 |Для рев’юераПримітка для модератора (необов’язково)Бачить лише модератор. Прискорює рев’ю.