В чем преимущество виртуального DOM по сравнению с обычным DOM
Что проверяют
Понимаете ли вы, какую проблему решает виртуальный DOM, или повторяете миф «виртуальный DOM быстрее настоящего». Сильный ответ содержит оговорку, что сам по себе он накладной расход. Следом спрашивают, как работает сравнение деревьев и зачем нужны ключи в списках.
Как отвечать
Виртуальный DOM это описание интерфейса в виде лёгких JS-объектов. Компонент при каждом рендере возвращает новое дерево, библиотека сравнивает его с предыдущим (reconciliation) и применяет к реальному DOM только разницу.
Главное преимущество не скорость, а модель разработки:
- декларативность: вы описываете, как интерфейс выглядит при данном состоянии, а не какие узлы добавить и удалить. Исчезает целый класс ошибок с рассинхроном состояния и разметки;
- приемлемая скорость без ручной работы: наивное «перерисовать всё через
innerHTML» медленное и сбрасывает фокус и введённый текст, а виртуальный DOM даёт точечные обновления автоматически; - батчинг: начиная с React 18 несколько обновлений состояния объединяются в один рендер даже в промисах и таймерах;
- независимость от платформы: то же дерево можно отрисовать в React Native или в строку при SSR.
Как работает сравнение: полный diff двух деревьев дорог, поэтому React использует эвристики. Разный тип элемента означает замену всего поддерева, а элементы списка сопоставляются по key.
Честно назовите цену: память на копию дерева и время на сравнение. Точечная ручная правка DOM всегда быстрее. Поэтому Svelte компилирует компоненты в прямые операции с DOM, SolidJS обновляет только узлы, зависящие от сигнала, Angular обходится без виртуального DOM, а у Vue появился Vapor Mode, работающий без него.
Где спотыкаются
Говорят, что виртуальный DOM быстрее обычного. Быстрее он только по сравнению с неаккуратными массовыми правками, а не с точечными.
Используют индекс массива как key. При вставке в начало или сортировке React переиспользует не те узлы, и состояние полей переезжает к соседним элементам.
Путают виртуальный DOM с Shadow DOM. Shadow DOM это механизм браузера для инкапсуляции веб-компонентов, к рендерингу React он отношения не имеет.