Почему концепция React Virtual DOM считается более эффективной, чем проверка грязной модели?

Я видел выступление React dev (Pete Hunt: React: переосмысление лучших практик - JSConf EU 2013), и докладчик упомянул, что грязная проверка модели может быть медленной. Но не является ли вычисление различий между виртуальными DOM на самом деле еще менее производительным, поскольку виртуальный DOM в большинстве случаев должен быть больше, чем модель?

Мне действительно нравится потенциальная мощь Virtual DOM (особенно рендеринг на стороне сервера), но я хотел бы знать все плюсы и минусы.

Ответ 1

Я являюсь основным автором модуля virtual-dom, поэтому я мог бы ответить на ваши вопросы. На самом деле есть две проблемы, которые необходимо решить здесь.

  • Когда я перерисовываю? Ответ: Когда я вижу, что данные грязные.
  • Как сделать рендер рентабельным? Ответ: использование виртуальной DOM для создания реального патча DOM

В React каждый из ваших компонентов имеет состояние. Это состояние похоже на наблюдаемое вы можете найти в нокауте или других библиотеках стилей MVVM. По сути, React знает , когда повторно отображает сцену, потому что она может наблюдать, когда эти данные изменяются. Грязная проверка медленнее, чем наблюдаемые, потому что вы должны опросить данные с регулярным интервалом и рекурсивно проверить все значения в структуре данных. Для сравнения, установка значения в состоянии будет сигнализировать слушателю о том, что какое-то состояние изменилось, поэтому React может просто прослушивать события изменения в состоянии и повторить рендеринг очереди.

Виртуальная DOM используется для эффективного повторного рендеринга DOM. Это не связано с грязной проверкой ваших данных. Вы можете повторно выполнить рендеринг с помощью виртуальной DOM с грязной проверкой или без нее. Вы правы в том, что есть некоторые накладные расходы при вычислении разницы между двумя виртуальными деревьями, но виртуальная разность DOM заключается в понимании необходимости обновления в DOM, а не изменения ваших данных. Фактически, алгоритм diff является самой грязной проверкой, но он используется, чтобы увидеть, загрязнен ли DOM.

Мы стремимся повторно визуализировать виртуальное дерево только при изменении состояния. Таким образом, использование наблюдаемого для проверки того, изменилось ли состояние, является эффективным способом предотвращения ненужных повторных рендерингов, что может вызвать множество ненужных различий в деревьях. Если ничего не изменилось, мы ничего не делаем.

Виртуальный DOM хорош, потому что он позволяет нам писать наш код, как если бы мы повторно отображали всю сцену. За кулисами мы хотим вычислить операцию патча, которая обновляет DOM, чтобы посмотреть, как мы ожидаем. Поэтому, хотя виртуальный алгоритм DOM diff/patch , вероятно, не является оптимальным решением, он дает нам очень хороший способ выразить наши приложения. Мы просто заявляем, что хотим, и React/virtual-dom будет определять, как сделать вашу сцену такой. Нам не нужно делать ручные манипуляции с DOM или путаться с предыдущим состоянием DOM. Нам также не нужно повторно отображать всю сцену, которая может быть намного менее эффективной, чем исправление ее.

Ответ 2

Недавно я прочитал подробную статью об алгоритме React diff: http://calendar.perfplanet.com/2013/diff/. Насколько я понимаю, что делает React быстрым:

  • Выполненные операции чтения/записи DOM.
  • Эффективное обновление только поддерева.

По сравнению с грязной проверкой ключевыми отличиями IMO являются:

  • Модель грязной проверки: компонент React явно задается как грязный при вызове setState, поэтому здесь нет никакого сравнения (данных). Для проверки грязности, сравнение (моделей) всегда происходит каждый цикл дайджеста.

  • Обновление DOM: операции DOM очень дороги, потому что изменение DOM также будет применяться и вычислять стили CSS, макеты. Сэкономленное время от ненужной модификации DOM может быть больше времени, затраченного на виртуальную DOM.

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

Ответ 3

Мне очень нравится потенциальная мощь Virtual DOM (особенно серверный рендеринг), но я хотел бы знать все плюсы и минусы.

- OP

Реакция - не единственная библиотека манипуляции с DOM. Я рекомендую вам понять альтернативы, прочитав эту статью из Auth0, которая содержит подробные объяснения и тесты. Я расскажу о своих плюсах и минусах, как вы спросили:

React.js 'Virtual DOM

введите описание изображения здесь

ПРОФИ

  • Быстрый и эффективный "отличный" алгоритм
  • Несколько интерфейсов (JSX, гиперссылка)
  • Достаточно легкий для работы на мобильных устройствах
  • Множество тяги и разума
  • Может использоваться без Реакт (т.е. как независимый движок)

CONS

  • Полная копия DOM в памяти (использование более высокой памяти)
  • Никакой дифференциации между статическими и динамическими элементами

Ember.js 'Glimmer

введите описание изображения здесь

ПРОФИ

  • Быстрый и эффективный алгоритм
  • Дифференциация между статическими и динамическими элементами
  • 100% совместим с API Ember (вы получаете преимущества без существенных обновлений существующего кода)
  • Легкое представление в памяти DOM

CONS

  • Предполагается использовать только в Ember
  • Доступен только один доступный интерфейс

Инкрементная DOM

введите описание изображения здесь

ПРОФИ

  • Сокращение использования памяти
  • Простой API
  • Легко интегрируется со множеством интерфейсов и фреймворков (подразумевается как базовый сервер шаблона с самого начала).

CONS

  • Не так быстро, как другие библиотеки (это возможно, см. приведенные ниже тесты)
  • Меньше ума и использования сообщества

Ответ 4

Вот комментарий члена команды React Себастьяна Маркбога, который проливает некоторый свет:

React выполняет анализ выходных данных (это известный сериализуемый формат, атрибуты DOM). Это означает, что исходные данные могут быть любого формата. Это могут быть неизменяемые структуры данных и состояния внутри замыканий.

Угловая модель не сохраняет ссылочную прозрачность и поэтому является изменчивой по своей природе. Вы изменяете существующую модель, чтобы отслеживать изменения. Что если ваш источник данных - это неизменяемые данные или новая структура данных каждый раз (например, ответ JSON)?

Грязная проверка и Object.observe не работают с состоянием области закрытия.

Эти две вещи очень ограничивают функциональные паттерны.

Кроме того, когда сложность вашей модели возрастает, делать грязное отслеживание становится все дороже. Однако, если вы выполняете только диффузию по визуальному дереву, например, React, он не увеличивается так сильно, поскольку объем данных, которые вы можете отобразить на экране в любой заданной точке, ограничен пользовательским интерфейсом. Приведенная выше ссылка "Пит" охватывает больше преимуществ.

https://news.ycombinator.com/item?id=6937668

Ответ 6

Виртуальный Дом не изобретен по реакции. Это часть HTML-домена. Он легкий и не связан с деталями реализации браузера.

Мы можем думать, что виртуальный DOM реагирует на локальную и упрощенную копию HTML DOM. Это позволяет React выполнять свои вычисления в этом абстрактном мире и пропускать "реальные" операции DOM, часто медленные и специфичные для браузера. На самом деле нет большой разницы между DOM и VIRTUAL DOM.

Ниже приведены рекомендации по использованию Virtual Dom (источник Virtual DOM в ReactJS):

Когда вы делаете:

document.getElementById('elementId').innerHTML = "New Value" Following thing happens:
  1. Браузер должен проанализировать HTML
  2. Удаляет дочерний элемент elementId
  3. Обновляет значение DOM новым значением
  4. Пересчитайте css для родителя и ребенка
  5. Обновите макет, то есть точные координаты каждого элемента на экране
  6. Пройдите по дереву рендеринга и раскрасьте его на экране браузера

Пересчет CSS и измененных макетов использует сложный алгоритм и они влияют на производительность.

А также обновление свойств DOM т.е. ценности. Это следует алгоритму.

Теперь предположим, что если вы обновляете DOM напрямую 10 раз, то все вышеперечисленные шаги будут выполняться по одному, и обновление алгоритмов DOM потребует времени для обновления значений DOM.

Вот почему Real DOM медленнее, чем виртуальный DOM.