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

Виртуальный DOM (Virtual DOM, или VDOM) в React Native работает по тем же принципам, что и в веб-версии React, но с ключевыми отличиями в реализации из-за отсутствия настоящего DOM в React Native. Вместо HTML-элементов и браузерного DOM, React Native использует виртуальное представление интерфейса, которое маппится на нативные компоненты платформы — такие как UIView в iOS или View в Android.

В основе React Native лежит идея декларативного программирования интерфейсов: разработчик описывает, что должно быть показано на экране, а React (в связке с виртуальным деревом) определяет, как это оптимально обновить.

Что такое Virtual DOM

Виртуальный DOM — это абстрактное дерево компонентов, хранящееся в памяти. Оно представляет собой объектную модель пользовательского интерфейса, созданную средствами JavaScript. Каждый компонент React возвращает JSX — описание интерфейса, которое преобразуется во внутреннюю структуру данных (ReactElement). Эта структура образует виртуальное дерево компонентов (VDOM), используемое React'ом для сравнения изменений.

Как работает Virtual DOM в React Native

Шаг 1: Рендеринг компонента

При первом рендере компонента:

  • React вызывает компонент-функцию или render() метода класса.

  • JSX преобразуется в JavaScript-объекты (React.createElement).

  • Эти объекты формируют виртуальное дерево (Virtual DOM).

  • React Native "переводит" это дерево в нативные представления: Text, View, Image и др.

Шаг 2: Сравнение деревьев (диффинг)

При изменении состояния (state) или свойств (props):

  • Компонент ререндерится и создаёт новое виртуальное дерево.

  • React сравнивает новое дерево с предыдущим (этот процесс называется diffing).

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

  • Эти изменения транслируются через bridge (или JSI/Fabric) в нативные UI-компоненты.

Шаг 3: Применение изменений

  • React вызывает соответствующие команды (например, обновить текст, изменить стиль, переместить элемент).

  • Эти команды проходят через UIManager, Fabric или bridge и применяются к нативным представлениям Android/iOS.

  • UI обновляется без полной перерисовки — только то, что действительно изменилось.

Пример: что происходит при обновлении

const App = () => {
const \[count, setCount\] = useState(0);
return (
<View>
<Text>Счётчик: {count}</Text>
<Button title="Увеличить" onPress={() => setCount(count + 1)} />
</View>
);
};
  1. При первом запуске count = 0, создаётся виртуальное дерево:

    • View → Text("Счётчик: 0") + Button(...)
  2. При нажатии кнопки вызывается setCount(1)

  3. React вызывает App(), генерирует новое дерево:

    • View → Text("Счётчик: 1") + Button(...)
  4. React сравнивает старое и новое дерево и видит, что изменился **только текст
    **

  5. Через bridge или JSI React Native обновляет только этот текст, не трогая весь View или Button

Отличие от браузерного DOM

Функция / аспект React (веб) React Native
Реальный DOM Браузерный DOM Нативные компоненты iOS/Android
--- --- ---
Элемент div, span, h1 HTML DOM-элементы View, Text, Image и пр.
--- --- ---
Обновления DOM-операции через браузерный API Команды в UIManager через bridge
--- --- ---
Цель Virtual DOM Минимизировать перерисовки DOM Минимизировать bridge и UI-апдейты
--- --- ---

Компоненты, Virtual DOM и Shadow Tree

React Native не работает напрямую с DOM. Вместо этого:

  1. Компоненты React описывают UI на уровне **Virtual DOM
    **
  2. React Native транслирует VDOM в Shadow Tree (внутреннее представление компонентов, которое учитывает стили и позиционирование с помощью Yoga)

  3. Затем Shadow Tree преобразуется в native views (например, UIView, TextView и т.д.)

Yoga — это движок расчёта макета (layout engine), разработанный Facebook, реализующий Flexbox для React Native. Он принимает размеры и стили компонентов из Shadow Tree и определяет точные координаты и размеры для отрисовки.

Обновление UI — важные этапы

  1. **Реактивность
    **

    • Любое изменение props или state вызывает ререндер компонента.
  2. **Реконструкция VDOM
    **

    • Новый React Element создаётся и сравнивается со старым.
  3. **Diffing
    **

    • React определяет, какие узлы изменились.
  4. **Сериализация
    **

    • Только изменённые части сериализуются и передаются через bridge (или JSI).
  5. **Команды обновления
    **

    • Native UI получает инструкции (например, обновить текст, применить стиль, изменить позицию).
  6. **Отрисовка
    **

    • Обновления применяются в нативной среде через платформенные виджеты (например, TextView, UIView и др.)

Оптимизация производительности VDOM в React Native

  1. Мемоизация компонентов (React.memo, useMemo, useCallback)

  2. **Оптимизированный FlatList/SectionList
    **

    • Эти компоненты используют windowing (отрисовка только видимых элементов)
  3. **Не мутировать объекты/массивы в props
    **

    • Передавать новые ссылки, если содержимое изменилось
  4. **Избегать лишних ререндеров
    **

    • Использовать shouldComponentUpdate, React.memo или useEffect с правильными зависимостями
  5. **Использовать key в списках
    **

    • Для оптимального диффинга при изменении элементов

Как Virtual DOM связан с bridge

  • Virtual DOM работает внутри JS-движка (например, Hermes или JavaScriptCore).

  • После сравнения виртуальных деревьев React определяет diff (разницу).

  • Эта разница передаётся через bridge в нативную часть, где UI обновляется.

  • Bridge может стать узким местом (bottleneck), особенно при большом числе обновлений.

Чтобы уменьшить нагрузку на bridge:

  • React Native внедряет новую архитектуру (Fabric + JSI)

  • Fabric устраняет необходимость в сериализации: обновления передаются напрямую

  • Улучшается производительность и отзывчивость интерфейса

Новый рендерер: Fabric и влияние на Virtual DOM

Fabric — это новый UI-рендерер React Native. Он всё ещё использует Virtual DOM, но меняет архитектуру взаимодействия с нативным UI:

  • Вместо bridge используется JSI (JavaScript Interface)

  • Снижается задержка между JS и нативным кодом

  • Упрощён жизненный цикл компонентов

  • Улучшена поддержка синхронных обновлений (например, при анимациях)

С Fabric Virtual DOM становится ближе к нативной реализации, позволяя производить рендеринг быстрее и с меньшей стоимостью.

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