DOM и JS-фреймворки
В фреймворках React и Vue используется концепт «Virtual DOM». Это представление «реального» UI, то есть DOM-а в браузере пользователя, в виде объекта в JS. Этот объект хранится в памяти браузера и представляет собой такую же иерархическую структуру, что и настоящее DOM-дерево. Упрощённо говоря — так:
<div class="box"> <h1>Title</h1></div>const virtualNode = { type: "div", props: { className: "box", children: [ { type: "h1", props: { children: ["Title"], }, }, ], },};Зачем делать такую копию DOM-а в памяти? Это нужно для оптимизации работы с настоящим DOM-ом в браузере. Возьмём пример: в браузере отрисовано 1000 DOM-нод, среди них нужно заменить одну ноду. Брать и заменять всё содержимое родительской ноды — неоптимально.
Лучше будет:
-
Хранить предыдущее и новое состояние (в памяти, виртуальном DOM-е).
-
По специальному алгоритму найти различия между двумя состояниями.
-
И затем синхронизировать реальное и виртуальное представление DOM-а, обновив точечно только нужные части дерева.
Этот процесс «сверки» нод в React называется reconciliation (в русском уже адаптировалось «реконсиляция»). Полное сравнение двух DOM-деревьев может быть довольно «дорогим» по ресурсам, особенно когда нод в них много. Поэтому во фреймворках в алгоритмах сверки и обновления заложены допущения, позволяющие избежать трат слишком больших ресурсов компьютера.
Например:
-
В повторяющихся наборах (списках, листингах) каждая нода помечается уникальным «ключом» — атрибутом key. По таким «подсказкам от разработчика» (уникальным идентификаторам, хэшам) фреймворку легче сравнивать ноды в DOM-деревьях: можно распознать изменение, не залезая внутрь ноды и не ориентируясь на её очерёдность в списке. Задача сводится к работе с «набором ключей» (HashMap): фреймворк определяет появление элементов с новыми ключами или изменение порядка элементов по их ключам.
-
Если меняется тип DOM-ноды, например, с
<p>на<div>, то фреймворк заменит саму ноду и все её дочерние элементы целиком.