← Назад к вопросам

В чем разница между DOM и VDOM?

2.0 Middle🔥 61 комментариев
#Другое

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI28 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Разница между DOM и Virtual DOM

Хороший вопрос. Многие backend разработчики не знают это хорошо, но это importante для понимания как работает modern frontend.

DOM (Document Object Model)

DOM — это реальное представление HTML страницы в браузере. Это объект, который браузер создаёт и обновляет.

// HTML
<div id="app">
  <h1>Hello</h1>
  <p>World</p>
</div>

// DOM это объект в памяти браузера
const dom = {
  tagName: 'div',
  attributes: { id: 'app' },
  children: [
    { tagName: 'h1', text: 'Hello' },
    { tagName: 'p', text: 'World' }
  ]
}

Манипуляция DOM:

// JavaScript работает с реальным DOM
const element = document.getElementById('app');
element.innerHTML = '<h2>Updated</h2>';

// Это "дорого" (performance penalty)
// Браузер:
// 1. Парсит строку
// 2. Создаёт новые ноды
// 3. Удаляет старые ноды
// 4. Перерисовывает (reflow/repaint)
// 5. Перевычисляет CSS
// 6. Обновляет экран (render)

Virtual DOM (VDOM)

VDOM — это JavaScript объект который представляет структуру DOM, но НЕ реальный DOM.

// React/Vue/Svelte создают VDOM в памяти
const vdom = {
  type: 'div',
  props: { id: 'app' },
  children: [
    { type: 'h1', children: 'Hello' },
    { type: 'p', children: 'World' }
  ]
}

// VDOM это просто JavaScript объект
// Это очень быстро манипулировать объектами

Процесс обновления в React

// 1. State меняется
setCount(count + 1);

// 2. React создаёт новый VDOM (очень быстро)
const newVDOM = {
  type: 'div',
  children: [
    { type: 'h1', children: `Count: ${count + 1}` },
    { type: 'button', children: 'Increment' }
  ]
}

// 3. React сравнивает старый VDOM с новым (reconciliation)
const differences = diffVDOM(oldVDOM, newVDOM);
// Результат: обновить только h1, остальное не менять

// 4. React обновляет только измененные части в реальном DOM
document.querySelector('h1').textContent = `Count: ${count + 1}`;

// 5. Браузер перерисовывает только изменённую часть

Пример: Почему VDOM быстрее

// Без VDOM (jQuery / vanilla JS)
// Обновляется список из 1000 элементов

for (let i = 0; i < 1000; i++) {
  // Каждая строка = манипуляция DOM
  // Браузер переписывает и перерисовывает после каждой!
  document.body.innerHTML += `<div>${i}</div>`;
  // 1000x reflow, 1000x repaint 😱
}
// Результат: очень медленно (секунды)

// С VDOM (React)
const items = Array.from({ length: 1000 }, (_, i) => ({
  type: 'div',
  children: String(i)
}));

const vdom = { type: 'div', children: items };
// Создание VDOM = быстро (миллисекунды)

// React обновляет реальный DOM один раз батчем
// Браузер перерисовывает один раз
// Результат: очень быстро (миллисекунды)

Key Differences

ПараметрDOMVDOM
Где живётВ браузере (C++/Rust)В памяти (JavaScript)
ОбновлениеМедленно (affect render)Быстро (just objects)
РеальностьРеальный, видно на экранеВиртуальный, только данные
Прямой доступdocument.getElementById()VDOM это просто объект
СинхронизацияРучная (вы пишете код)Автоматическая (React/Vue)
MemoryСложная структураПростые объекты

Diffing Algorithm

Это ключ к производительности VDOM.

// Старый VDOM
const oldVDOM = {
  type: 'ul',
  children: [
    { type: 'li', key: '1', children: 'Item 1' },
    { type: 'li', key: '2', children: 'Item 2' },
    { type: 'li', key: '3', children: 'Item 3' }
  ]
}

// Новый VDOM (item 2 удалён)
const newVDOM = {
  type: 'ul',
  children: [
    { type: 'li', key: '1', children: 'Item 1' },
    { type: 'li', key: '3', children: 'Item 3' }
  ]
}

// React diffing:
// - Item 1: не изменился (пропусти)
// - Item 2: удалить (УДАЛИТЬ из DOM)
// - Item 3: не изменился но сдвинулся (просто переставить в DOM)

// Результат:
// - 1 операция удаления в реальном DOM
// - Без перестроения всего списка

Без key:

// Плохо: React не знает что это один и тот же элемент
// Будет:
// - Item 1 -> Item 1 (обновить текст)
// - Item 2 -> Item 3 (обновить текст)
// - Item 3 -> удалить
// 3 операции вместо 1

// Хорошо: с key React знает элементы
// Результат: 1 операция удаления

Где используется VDOM

// React
const App = () => (
  <div>
    <h1>Count: {count}</h1>
    <button onClick={() => setCount(count + 1)}>Increment</button>
  </div>
);
// JSX компилируется в VDOM

// Vue
const template = `
  <div>
    <h1>Count: {{ count }}</h1>
    <button @click="count++">Increment</button>
  </div>
`;
// Vue создаёт VDOM из template

// Svelte НЕ использует VDOM
// Вместо этого компилирует в DOM обновления напрямую
// Поэтому Svelte быстрее на очень больших приложениях

VDOM vs Real DOM Вызовы

Real DOM вызовы дорогие:

document.createElement() // дорого
element.appendChild()    // дорого
element.removeChild()    // дорого
element.textContent =    // дорого (reflow)
element.style.color =    // дорого (repaint)

VDOM вызовы дешевые:

const vdom = {};  // дешево
vdom.props = {};  // дешево
vdom.children = []; // дешево

Синхронизация VDOM -> DOM

// Этот процесс называется "mounting" и "updating"

// Mounting (первый раз)
const vdom = ReactElement;
const dom = ReactDOM.render(vdom, document.getElementById('root'));
// React создаёт реальные DOM ноды из VDOM

// Updating (state изменился)
setState(newState);
// React:
// 1. Создаёт новый VDOM
// 2. Сравнивает с старым
// 3. Обновляет только изменённые DOM ноды

Performance

Без VDOM (jQuery):

Manipulating 1000 elements:
- Time: 500-1000ms
- Reflows: 1000
- Repaints: 1000

С VDOM (React):

Manipulating 1000 elements:
- Time: 5-50ms
- Reflows: 1-2
- Repaints: 1

Key Takeaways

  1. DOM — это реальный браузерный объект, обновление дорого
  2. VDOM — это JS объект, обновление дешево
  3. Reconciliation — React сравнивает старый и новый VDOM
  4. Batching — React батчит обновления для одного reflow
  5. Keys — помогают React правильно сопоставлять элементы

Для backend разработчика

Это важно потому что:

  • API дизайн — VDOM нужен правильный JSON формат
  • Data fetching — должен быть оптимальным для reconciliation
  • WebSocket — обновления должны быть частичными
  • Performance — backend может повлиять на frontend speed

Примерно как разница между отправить все данные (дорого) vs отправить только изменения (дешево).