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

349

Я видел беседу React в http://www.youtube.com/watch?v=x7cQ3mrcKaY, и оратор отметил, что грязно- проверка модели может быть медленной. Но не вычисляет ли разница между виртуальными DOM на самом деле еще менее результативен, поскольку виртуальный DOM в большинстве случаев должен быть больше, чем модель?

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

  • 0
    Я думаю, что вы могли бы упомянуть и этот доклад на youtube.com/watch?v=-DX3vJiqxm4, где он специально говорит о тестах.
Теги:
dom
virtual-dom

5 ответов

433

Я являюсь основным автором модуля 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. Нам также не нужно повторно отображать всю сцену, которая может быть намного менее эффективной, чем исправление ее.

  • 1
    React выполняет грязную проверку реквизита компонентов? Я спрашиваю, потому что нет функции setProps ().
  • 2
    Есть setProps: facebook.github.io/react/docs/component-api.html#setprops
Показать ещё 9 комментариев
128

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

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

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

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

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

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

  • 1
    На самом деле я тоже прочитал несколько статей, поэтому я теперь (по крайней мере, в целом), как это работает, я просто хотел выяснить, почему это может быть более эффективным, чем грязная проверка модели. И 1) Да, он не сравнивает модели, но сравнивает гораздо большую виртуальную дом 2) Грязная проверка модели дает нам возможность обновлять только то, что нужно (как это делает Angular)
  • 0
    Я считаю, что нужно сравнивать только те части виртуального DOM, которые соответствуют измененному компоненту, в то время как грязная проверка выполняется в каждом цикле дайджеста, для каждого значения в каждой области, даже если ничего не изменилось. Если большой объем данных изменился, то Virtual DOM будет менее эффективным, но не для небольших изменений данных.
Показать ещё 6 комментариев
70

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

- OP

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

React.js 'Virtual DOM

Изображение 2688

ПРОФИ

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

CONS

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

Ember.js 'Glimmer

Изображение 2689

ПРОФИ

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

CONS

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

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

Изображение 2690

ПРОФИ

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

CONS

  • Не так быстро, как другие библиотеки (это возможно, см. приведенные ниже тесты)
  • Меньше ума и использования сообщества
  • 0
    Представление манипуляций с DOM в ReactJS кажется мне не слишком удачным. Виртуальный DOM ReactJS - это тот, который полностью изменяется, а не фактический DOM - правильно? Я смотрю на оригинальную статью, на которую ссылаются ссылки, и вот что я вижу - teropa.info/images/onchange_vdom_change.svg . teropa.info/blog/2015/03/02/...
34

Здесь комментарий члена команды React Sebastian Markbåge, который проливает некоторый свет:

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

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

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

Очевидно, эти две вещи очень ограничивают функциональные шаблоны.

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

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

  • 2
    На самом деле о последнем абзаце: это должно быть неправильно: модель больше, чем виртуальный DOM, потому что для каждого значения модели (в большинстве случаев) имеется по крайней мере один виртуальный элемент DOM (и обычно намного больше одного). Почему я хочу модель, которая не показана?
  • 2
    Пагинация кэшированных коллекций.
-2

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

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

Ниже приведены точки, в которых используется виртуальный дом (источник https://hackernoon.com/virtual-dom-in-reactjs-43a3fdb1d130):

Когда вы выполните:

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.

  • 0
    Пример: если вы модифицируете dom напрямую или через виртуальный dom, то, наконец, в обоих случаях вы меняете dom.
  • 0
    Да, в обоих случаях мы обновляем dom, но в случае виртуального dom он обновляет только тот ключ (только то, что определяется алгоритмом, отличным от алгоритма) или только тег элемента. Принимая во внимание, что обновление dom обновляет или полностью обновляет весь dom.
Показать ещё 2 комментария

Ещё вопросы

Сообщество Overcoder
Наверх
Меню