Virtual DOM в React
Virtual DOM — это облегчённая копия реального DOM, хранящаяся в оперативной памяти.
React обновляет эту копию вместо непосредственного изменения реального DOM, чтобы не вызывать лишние «дорогие» операции (layout
, painting
, reflow
) в браузере.
Когда все изменения внесены, React сравнивает старую и новую версии Virtual DOM (diffing) и точечно обновляет реальный DOM (reconciliation).
Эвристический алгоритм O(n)
React применяет эффективный алгоритм с двумя ключевыми предположениями:
-
Разные типы элементов → разные деревья
- Два элемента с разными типами произведут разные деревья. При сравнении двух деревьев первым делом React сравнивает два корневых элемента. Когда корневые элементы имеют различные типы, React уничтожает старое дерево и строит новое с нуля.
- Если тип не меняется, обновляются лишь изменённые атрибуты и дочерние узлы.
-
Значение
key
для потомков- При перестановке элементов в списке ключи (
key
) позволяют React понять, какие элементы сохранились, какие добавились и какие удалились. - Это экономит ресурсы и снижает перерисовки.
- При перестановке элементов в списке ключи (
Шаги обновления (упрощённо)
-
Обновление Virtual DOM
React фиксирует изменения (например, вызовsetState
илиuseState
). -
Diffing
React сравнивает предыдущий Virtual DOM с новым, выявляя отличия. -
Reconciliation
- Только изменённые части реального DOM перерисовываются.
- Обновления выполняются пакетно, а не после каждого небольшого изменения.
Ключевые моменты
- Минимизация работы с реальным DOM: React сводит к минимуму «дорогие» браузерные операции.
- Инкапсуляция: Компоненты работают со своим состоянием без ручного контроля над reflow/layout.
- Простое масштабирование: Алгоритм позволяет писать более масштабируемый и поддерживаемый код.
Важный нюанс:
Если родительский компонент рендерится, то по умолчанию его дочерние компоненты также повторно рендерятся, если не применяются дополнительные оптимизации (React.memo
, shouldComponentUpdate
и т.д.)