Archived resourceLegacy URL

Rendering, Repaint, Reflow and Restyle Ukrainian Translation

Archived resource from a previous version of Stoodio.org, restored at its legacy URL to preserve historical references and backlinks.

Legacy URL
/archive-rendering-repaint-reflowrelayout-restyle

Рендеринг сторінки

Після того як браузер завантажив HTML, CSS і JavaScript, він має перетворити ці дані на видиму сторінку. Спочатку HTML розбирається у DOM-дерево: кожен тег стає вузлом, а текст між тегами також отримує своє представлення. Потім браузер читає CSS і формує набір правил, які описують зовнішній вигляд елементів. У цьому процесі враховується каскад: стандартні стилі браузера, стилі користувача, стилі автора сторінки, імпортовані та інлайнові правила.

Далі починається побудова дерева рендерингу. Воно не є точною копією DOM. Елементи, які не мають візуального представлення, наприклад head або блоки з display: none, не потрапляють у це дерево. Натомість один DOM-вузол може породжувати кілька візуальних блоків, особливо якщо текст розбивається на кілька рядків. Кожен блок має розміри, відступи, рамки, положення і набір властивостей, які потрібні для малювання.

Схема рендерингу в браузері

DOM, render tree і видима частина сторінки

Автор пояснює це на простому прикладі HTML-сторінки. У DOM будуть представлені html, head, title, body, абзаци, блоки, зображення і текстові вузли. Але дерево рендерингу міститиме лише те, що треба показати. Прихований div зникне, вміст head також не буде малюватися, а абзац може розділитися на кілька лінійних блоків.

Коренем дерева рендерингу є область, у якій сторінка розміщується у вікні браузера. Для WebKit автор згадує RenderView; у термінах CSS це близько до початкового контейнера, тобто прямокутника viewport. Щоб зрозуміти, що і де показати, браузер проходить дерево згори вниз і розраховує геометрію елементів.

Reflow і repaint

Перший розрахунок макета сторінки неминучий. Після нього будь-яка зміна, що впливає на розміри або положення елементів, може спричинити reflow - повторне компонування. Якщо змінюється лише зовнішній вигляд без геометрії, наприклад колір тексту чи фону, достатньо repaint - перемальовування відповідної області.

Reflow зазвичай дорожчий, тому що зміна одного елемента може змусити браузер перерахувати його сусідів, батьківські блоки або навіть значну частину сторінки. Додавання і видалення DOM-вузлів, зміна класів, шрифтів, відступів, ширини, висоти, приховування через display: none, зміна розміру вікна і навіть прокручування можуть впливати на продуктивність.

Приклад вимірювання змін макета

Чому браузери не безпорадні

Сучасні браузери намагаються не виконувати зайву роботу після кожної дрібної зміни. Вони можуть накопичувати правки і застосовувати їх пакетом. Проблема виникає, коли скрипт спочатку змінює стиль, а потім одразу читає властивість, яка залежить від актуального макета, наприклад offsetLeft, offsetWidth або обчислений стиль. Тоді браузер змушений синхронно завершити розрахунки, щоб повернути правильне значення.

Саме тому погана практика - у циклі чергувати запис стилів і читання геометрії. Краще спочатку зібрати всі потрібні значення, а потім застосувати зміни, або навпаки згрупувати модифікації так, щоб браузер міг оптимізувати роботу.

Як мінімізувати витрати

Автор радить змінювати класи замість багатьох окремих стилів, працювати з елементом поза основним потоком документа, приховувати його на час масових змін або використовувати фрагмент документа для створення великих частин DOM. Ще один прийом - уникати складних селекторів і надмірної залежності макета від багатьох взаємопов'язаних елементів.

Головна думка статті: продуктивність сторінки залежить не лише від швидкості JavaScript. Навіть короткий скрипт може зробити інтерфейс повільним, якщо він постійно змушує браузер перераховувати макет і перемальовувати екран.

Інструменти профілювання рендерингу