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

В чем разница между виртуальным и реальным DOM?

1.6 Junior🔥 241 комментариев
#Браузер и сетевые технологии

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

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

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

В чем разница между виртуальным и реальным DOM?

Что такое реальный DOM?

Реальный DOM (Real DOM) — это живое представление HTML документа в браузере. Это объект, который браузер создаёт при загрузке страницы и которым он управляет. Каждый элемент на странице — это узел в реальном DOM.

// Реальный DOM — это то, что вы видите на странице
const element = document.getElementById('myElement');
element.innerHTML = 'Hello'; // Изменение реального DOM

// Браузер сразу перерисует страницу (reflow и repaint)

Что такое виртуальный DOM?

Виртуальный DOM (Virtual DOM) — это JavaScript представление DOM структуры, хранящееся в памяти приложения. Это легковесная копия реального DOM, которая существует только в JavaScript и служит для отслеживания изменений.

// Виртуальный DOM в React — это объект
const vdom = {
  type: 'div',
  props: { id: 'myElement' },
  children: [
    { type: 'h1', children: 'Hello' }
  ]
};

// Это НЕ изменяет реальный DOM сразу

Основные различия

АспектРеальный DOMВиртуальный DOM
ЛокацияВ браузере (управляется браузером)В памяти приложения (JavaScript)
ПроизводительностьМедленнее (изменения вызывают reflow/repaint)Быстрее (батчинг, дифференцирование)
СинхронностьСинхронные обновленияАсинхронное дифференцирование
СвязьНеизменное для приложенияМожет быть легко создано и пересоздано
ОтладкаВидно в DevTools сразуТребует специальных инструментов

Как работает реальный DOM

// Каждое изменение вызывает reflow и repaint
const element = document.getElementById('box');

element.style.width = '100px';  // Reflow + Repaint
element.style.height = '100px'; // Reflow + Repaint
element.style.color = 'red';    // Repaint

// Браузер перерисовал страницу 3 раза!
// Это дорого в плане производительности

Как работает виртуальный DOM (React)

// Шаг 1: Создание нового Virtual DOM
const newVDOM = {
  type: 'div',
  props: { id: 'box' },
  children: 'Hello'
};

// Шаг 2: Сравнение с предыдущим (diffing)
const oldVDOM = { /* старая версия */ };
const changes = diff(oldVDOM, newVDOM);

// Шаг 3: Применение ТОЛЬКО необходимых изменений
changes.forEach(change => {
  applyToRealDOM(change);
});

Пример: React reconciliation

// ❌ Без Virtual DOM (в ванильном JavaScript)
function updateUI() {
  document.getElementById('name').textContent = 'John';
  document.getElementById('age').textContent = '30';
  document.getElementById('email').textContent = 'john@example.com';
  document.getElementById('city').textContent = 'NYC';
  
  // Каждое изменение заставляет браузер переделать макет
  // и перерисовать — дорого!
}

// ✅ С Virtual DOM (React)
function UserComponent() {
  const [user] = useState({
    name: 'John',
    age: 30,
    email: 'john@example.com',
    city: 'NYC'
  });

  return (
    <div>
      <p>{user.name}</p>
      <p>{user.age}</p>
      <p>{user.email}</p>
      <p>{user.city}</p>
    </div>
  );
}
// React создаст Virtual DOM, сравнит с предыдущим,
// найдёт только изменённые элементы и обновит их

Производительность: пакетирование обновлений

// ❌ Множественные обновления реального DOM
const element = document.getElementById('box');
element.style.width = '100px';   // Reflow 1
element.style.height = '100px';  // Reflow 2
element.style.color = 'red';     // Repaint
element.style.backgroundColor = 'blue'; // Repaint

// 4 операции = 4 браузерных события!

// ✅ React батчирует обновления
setState({ 
  width: '100px',
  height: '100px',
  color: 'red',
  backgroundColor: 'blue'
});
// React выполнит одно diffing,
// применит все изменения за один reflow/repaint

Что происходит при обновлении

Реальный DOM в чистом JavaScript:

Изменение в коде
     ↓
Браузер анализирует DOM
     ↓
Вычисляет новый макет (Reflow)
     ↓
Перерисовывает страницу (Repaint)
     ↓
Отображает результат пользователю

Virtual DOM в React:

Изменение в коде
     ↓
Создание нового Virtual DOM
     ↓
Diffing (сравнение старого и нового)
     ↓
Определение минимальных изменений
     ↓
Применение ТОЛЬКО этих изменений к реальному DOM
     ↓
Браузер делает один Reflow/Repaint
     ↓
Отображает результат пользователю

Когда Virtual DOM помогает, а когда нет

Помогает (сложные приложения с частыми обновлениями):

// Список с 1000 элементами, обновляется каждую секунду
function LargeList({ items }) {
  return (
    <ul>
      {items.map(item => (
        <li key={item.id}>
          {item.name} - {item.status} - {item.value}
        </li>
      ))}
    </ul>
  );
}
// React найдёт, что изменилось, обновит только это
// Браузер не пересчитает весь макет заново

Не помогает (простые приложения, редкие обновления):

// Одна кнопка, которую кликают раз в час
// Издержки Virtual DOM (создание, сравнение) не стоят того
function SimpleButton() {
  return <button onClick={() => alert('Clicked')}>Click me</button>;
}

Что НЕ делает Virtual DOM

// Virtual DOM НЕ решает всё

// Это все ещё проблема:
function BadComponent() {
  const items = items.map(item => (
    <ListItem key={Math.random()} /> // Bad! key меняется каждый раз
  ));
  // Virtual DOM не может помочь здесь
  // React пересоздаст все элементы
}

// Virtual DOM не помогает с CSS рассчётами:
function SlowRender() {
  // Это всё ещё медленно
  const position = calculateComplexPosition();
  const style = calculateComplexStyle();
  
  return <div style={style}>Complex calc</div>;
}

Альтернативные подходы

Svelte — компилирует код в vanilla JavaScript без Virtual DOM:

// Svelte
let count = 0;

$: doubled = count * 2; // Реактивность без Virtual DOM

<button on:click={() => count++}>
  Count: {count}, Doubled: {doubled}
</button>

Vue — использует реактивную систему, не Virtual DOM (хотя в v3 тоже есть Virtual DOM опционально)

Preact — минималистичный Virtual DOM фреймворк (3 KB)

Заключение

Реальный DOM — это то, что браузер отображает. Виртуальный DOM — это JavaScript представление, используемое фреймворками для оптимизации обновлений. Virtual DOM помогает при сложных приложениях с частыми обновлениями, так как батчирует изменения и обновляет только необходимое. Однако это добавляет слой абстракции, поэтому для простых приложений может быть не эффективным. Важно понимать, что Virtual DOM — это инструмент оптимизации, а не магическое решение для всех проблем производительности.