В чем разница render tree и DOM
Что проверяют
Понимаете ли вы, как браузер превращает разметку в пиксели и где на этом пути появляются дорогие операции. Следом почти всегда спрашивают, чем reflow отличается от repaint и почему display: none и visibility: hidden ведут себя по-разному.
Как отвечать
Покажите оба дерева как этапы одного конвейера:
- DOM: объектная модель документа, которую браузер строит при разборе HTML. В ней все узлы, включая
<head>,<script>, комментарии и скрытые элементы. С ней работает JavaScript черезquerySelector,appendChildи остальной API; - CSSOM: такое же дерево для стилей, собранное из CSS-файлов, блоков
<style>и атрибутовstyle; - render tree: результат объединения DOM и CSSOM. В него попадают только узлы, которые будут нарисованы, и у каждого уже посчитаны итоговые стили. Элемент с
display: noneи всё его поддерево сюда не входят, а элемент сvisibility: hiddenвходит, потому что занимает место. Псевдоэлементы::beforeи::afterесть в render tree, хотя в DOM их нет.
Дальше назовите этапы после построения дерева: layout (расчёт геометрии, он же reflow), paint (заливка пикселей по слоям) и composite (сборка слоёв, часто на GPU). В Chromium эту структуру сейчас называют layout tree, смысл тот же.
Практический вывод: изменение DOM или стилей запускает пересчёт стилей, а дальше всё зависит от свойства. Смена width или top требует layout, смене color хватает перерисовки, а transform и opacity на отдельном слое обходятся одним композитингом. Поэтому анимации строят на них.
Где спотыкаются
Путают render tree с virtual DOM. Virtual DOM это структура React в памяти JavaScript, браузер о ней ничего не знает.
Считают, что render tree повторяет DOM один к одному. Скрытые узлы из него выпадают, псевдоэлементы добавляются, а вложенность может отличаться.
Не знают про принудительный синхронный layout. Если в цикле менять стиль и тут же читать offsetHeight или getBoundingClientRect(), браузер пересчитывает геометрию на каждой итерации. Чтения и записи нужно группировать.