Что такое virtual dom


Virtual DOM (виртуальный DOM) — это концепция и технология, используемая в современных JavaScript-фреймворках, таких как React, Vue и других, для повышения производительности обновления пользовательского интерфейса. Виртуальный DOM представляет собой абстракцию реального DOM — облегчённую копию структуры HTML-документа, которая существует в памяти и используется для более эффективного управления обновлениями страницы.

1. Что такое DOM

DOM (Document Object Model) — это объектная модель HTML-документа. Браузер представляет каждую HTML-страницу в виде дерева узлов, где каждый элемент, текст, атрибут — это объект. Изменения DOM (например, изменение текста в <div>, добавление элемента, изменение стиля и т.д.) приводят к:

  • повторному вычислению стилей (recalculate styles),

  • перерасчёту компоновки (reflow),

  • перерисовке (repaint),

  • возможному изменению структуры дерева браузера (layout tree, render tree).

Эти операции дорогие по ресурсам, особенно при частом обновлении DOM. Именно поэтому обновления DOM следует делать как можно реже и эффективнее.

2. Проблема: прямое управление DOM медленно

Когда веб-приложение работает с реальным DOM напрямую, каждое изменение элемента (например, изменение текста кнопки при клике) может вызывать повторную отрисовку. Если таких операций много, страница начинает тормозить.

Всё усложняется, когда:

  • У интерфейса множество зависимостей между элементами.

  • Состояние данных меняется часто (например, в чате, ленте новостей).

  • Нужно поддерживать отзывчивость интерфейса.

Чтобы избежать постоянного взаимодействия с реальным DOM, фреймворки используют виртуальный DOM.

3. Virtual DOM: что это такое

Виртуальный DOM — это объектная структура, которая копирует реальную DOM-структуру, но существует в оперативной памяти и не отображается на экране. Это просто JavaScript-объекты, описывающие структуру интерфейса.

Когда требуется обновить интерфейс:

  1. Сначала изменения вносятся во виртуальный DOM.

  2. После этого происходит сравнение (diffing) нового и старого виртуального DOM.

  3. Вычисляется минимальный набор изменений (patch), который нужно внести в настоящий DOM.

  4. Эти изменения применяются к реальному DOM.

Такой подход минимизирует количество операций с реальным DOM, что делает работу интерфейса более эффективной и быстрой.

4. Как устроен Virtual DOM на практике

Представим простой HTML-фрагмент:

&lt;div&gt;
&lt;h1&gt;Hello&lt;/h1&gt;
&lt;p&gt;World&lt;/p&gt;
&lt;/div&gt;

В виртуальном DOM это будет представлено как объект:

{
type: 'div',
props: {},
children: \[
{
type: 'h1',
props: {},
children: \['Hello'\]
},
{
type: 'p',
props: {},
children: \['World'\]
}
\]
}

Каждый элемент представлен узлом с типом, свойствами (атрибутами) и дочерними элементами.

Если изменить <h1>Hello</h1> на <h1>Hi</h1>, фреймворк не будет перерисовывать весь div, а только обновит текст в нужном узле h1, потому что при сравнении виртуальных DOM он увидит, что изменился только текст.

5. Diffing: алгоритм сравнения Virtual DOM

Diffing — это процесс, в котором фреймворк сравнивает два виртуальных дерева: старое и новое. Алгоритм пытается понять:

  • Какие элементы были добавлены.

  • Какие удалены.

  • Какие обновлены (например, изменился текст или атрибуты).

Пример:

// Старый VDOM
const oldVDOM = createElement('ul', {}, \[
createElement('li', { key: 'a' }, 'A'),
createElement('li', { key: 'b' }, 'B')
\]);
// Новый VDOM
const newVDOM = createElement('ul', {}, \[
createElement('li', { key: 'b' }, 'B'),
createElement('li', { key: 'a' }, 'A')
\]);

Фреймворк увидит, что li с ключами a и b поменялись местами. Благодаря ключам он поймёт, что узлы не были удалены и созданы заново, а просто поменяли порядок — это позволит эффективно обновить реальный DOM, не пересоздавая элементы.

6. Patch: применение изменений к настоящему DOM

После diffing-а, создаётся patch — список изменений. Этот список может включать:

  • обновление текста;

  • замена узла;

  • обновление атрибутов (class, id, style и т.д.);

  • вставка или удаление узлов;

  • изменение порядка дочерних элементов.

Этот patch применяет минимальные изменения в DOM, избегая полной перерисовки всего дерева. Это даёт значительный прирост производительности.

7. Почему Virtual DOM быстрее

Несмотря на то, что добавляется «дополнительный шаг» — создание и сравнение виртуального дерева, в реальности это быстрее, чем прямое управление DOM, потому что:

  • операции с JavaScript-объектами в памяти намного быстрее, чем с DOM-элементами;

  • реальный DOM не изменяется до тех пор, пока не будет вычислен точный набор изменений;

  • благодаря использованию ключей и оптимизаций diffing-а, можно избежать ненужной работы.

8. Virtual DOM и React

React — один из фреймворков, который популяризировал концепцию Virtual DOM. Он реализует виртуальное дерево компонентов через вызов функций React.createElement() или синтаксис JSX:

const element = &lt;h1&gt;Hello&lt;/h1&gt;;

Внутри React это превращается в виртуальный объект, который можно сравнивать и обновлять без манипуляции реальным DOM до момента рендеринга.

React также использует Fiber — новую архитектуру виртуального DOM (начиная с версии React 16), которая позволяет приостанавливать и возобновлять работу над обновлениями, обеспечивая плавную отрисовку даже в больших приложениях.

9. Virtual DOM в других фреймворках

  • Vue.js также использует Virtual DOM, особенно начиная с Vue 2. Он делает это похожим образом, создавая лёгкие виртуальные представления компонентов.

  • Snabbdom, Inferno, Preact — это более лёгкие библиотеки, реализующие виртуальный DOM отдельно от больших фреймворков.

  • В некоторых случаях Virtual DOM не используется (например, в Svelte), поскольку эти фреймворки компилируют код в нативные операции DOM во время сборки и избегают runtime diffing.

10. Преимущества Virtual DOM

  • Более производительное обновление интерфейса.

  • Упрощение логики UI: разработчику не нужно вручную контролировать, когда обновлять DOM.

  • Позволяет реализовать однонаправленный поток данных, упрощая отладку и тестирование.

  • Обеспечивает предсказуемость и детерминированность — результат зависит только от состояния, а не от текущего состояния DOM.

11. Недостатки Virtual DOM

  • Не всегда быстрее: для очень простых приложений с редкими изменениями можно добиться большей производительности без виртуального DOM.

  • Добавляет сложность и накладные расходы на промежуточное представление (создание, сравнение деревьев).

  • Необходимость изучать архитектуру компонентов и управление состоянием, особенно в таких фреймворках, как React.