395 Stimmen

Warum gilt das Konzept des Virtual DOM von React als performanter als das Dirty-Model-Checking?

Ich habe einen React Entwickler-Talk bei (Pete Hunt: React: Rethinking best practices -- JSConf EU 2013) gesehen und der Sprecher erwähnte, dass das dirty-checking des Modells langsam sein kann. Aber ist das Berechnen des Unterschieds zwischen virtuellen DOMs tatsächlich noch weniger performant, da der virtuelle DOM in den meisten Fällen größer sein sollte als das Modell?

Ich mag das Potenzial der Virtual DOM (insbesondere das serverseitige Rendern) wirklich gern, würde aber gerne alle Vor- und Nachteile kennen.

511voto

Matt Esch Punkte 22161

Ich bin der Hauptautor eines virtual-dom Moduls, daher könnte ich in der Lage sein, Ihre Fragen zu beantworten. Es gibt tatsächlich 2 Probleme, die hier gelöst werden müssen

  1. Wann sollte ich neu rendern? Antwort: Wenn ich feststelle, dass die Daten verändert wurden.
  2. Wie kann ich effizient neu rendern? Antwort: Durch Verwendung eines virtuellen DOMs, um einen echten DOM-Patch zu erzeugen

In React hat jeder Ihrer Komponenten einen Zustand. Dieser Zustand ist ähnlich wie ein Observable, das Sie in Knockout oder anderen MVVM-Style-Bibliotheken finden könnten. Im Wesentlichen weiß React wann, die Szene neu zu rendern, weil es beobachten kann, wann sich diese Daten ändern. Das Prüfen auf Veränderungen ist langsamer als Observables, da Sie die Daten in regelmäßigen Abständen abfragen und alle Werte in der Datenstruktur rekursiv überprüfen müssen. Im Vergleich dazu signalisiert das Setzen eines Werts im Zustand einem Zuhörer, dass sich ein Zustand geändert hat, sodass React einfach auf Änderungsereignisse im Zustand hören und das Neuzeichnen planen kann.

Der virtuelle DOM wird für eine effiziente Neurenderung des DOMs verwendet. Dies hat eigentlich nichts mit dem Überprüfen auf Veränderungen Ihrer Daten zu tun. Sie könnten mit oder ohne Prüfung auf Veränderungen auf einem virtuellen DOM neu rendern. Sie haben recht, dass etwas Overhead bei der Berechnung des Unterschieds zwischen zwei virtuellen Baumstrukturen besteht, aber der virtuelle DOM-Unterschied dient dazu zu verstehen, was im DOM aktualisiert werden muss und nicht ob sich Ihre Daten geändert haben. Tatsächlich ist der Diff-Algorithmus selbst ein Prüfer für Veränderungen, wird jedoch verwendet, um festzustellen, ob der DOM selbst verändert wurde.

Unser Ziel ist es, den virtuellen Baum nur dann neu zu rendern, wenn sich der Zustand ändert. Wenn wir ein Observable verwenden, um festzustellen, ob sich der Zustand geändert hat, ist das eine effiziente Möglichkeit, unnötige Neurenders zu verhindern, die viele unnötige Baumunterschiede verursachen würden. Wenn sich nichts geändert hat, tun wir nichts.

Ein virtueller DOM ist praktisch, weil er es uns erlaubt, unseren Code zu schreiben, als würden wir die gesamte Szene neu rendern. Hinter den Kulissen möchten wir eine Patch-Operation berechnen, die den DOM aktualisiert, um so auszusehen, wie wir es erwarten. Während der virtuelle DOM-Diff/Patch-Algorithmus wahrscheinlich nicht die optimale Lösung ist, bietet er uns einen sehr schönen Weg, um unsere Anwendungen auszudrücken. Wir erklären einfach genau, was wir wollen, und React/virtual-dom wird herausfinden, wie Ihre Szene so aussehen soll. Wir müssen keine manuelle DOM-Manipulation durchführen oder verwirrt über den vorherigen DOM-Zustand sein. Wir müssen auch nicht die gesamte Szene neu rendern, was viel weniger effizient sein könnte, als sie zu patchen.

135voto

tungd Punkte 14027

Ich habe kürzlich einen ausführlichen Artikel über den Diff-Algorithmus von React hier gelesen: http://calendar.perfplanet.com/2013/diff/. Soweit ich verstehe, was React schnell macht, ist:

  • Batched DOM-Lese- / Schreibvorgänge.
  • Effizientes Update des Teilbaums.

Verglichen mit Dirty-Checking sind meiner Meinung nach die wichtigsten Unterschiede:

  1. Model-Dirty-Checking: Das React-Komponente wird explizit als dirty festgelegt, wenn setState aufgerufen wird, daher ist hier kein Vergleich (der Daten) erforderlich. Beim Dirty-Checking erfolgt der Vergleich (der Modelle) immer in jeder Digest-Schleife.

  2. DOM-Aktualisierung: DOM-Operationen sind sehr teuer, weil das Modifizieren des DOM auch CSS-Stile und Layouts anwendet und berechnet. Die gesparte Zeit durch unnötige DOM-Änderungen kann länger sein als die Zeit, die für das Diffen des virtuellen DOM aufgewendet wird.

Der zweite Punkt ist noch wichtiger für nicht-triviale Modelle wie solche mit einer großen Anzahl von Feldern oder einer großen Liste. Eine Feldänderung eines komplexen Modells führt nur zu den für DOM-Elemente erforderlichen Operationen im Zusammenhang mit diesem Feld, anstatt der gesamten Ansicht / Vorlage.

76voto

falsarella Punkte 12028

Ich mag das Potenzial der Virtual DOM wirklich (besonders das serverseitige Rendern), aber ich würde gerne alle Vor- und Nachteile kennen.

-- OP

React ist nicht die einzige DOM-Manipulationsbibliothek. Ich ermutige dich, die Alternativen zu verstehen, indem du diesen Artikel von Auth0 liest, der eine ausführliche Erklärung und Benchmarks enthält. Ich werde hier ihre Vor- und Nachteile hervorheben, wie du gefragt hast:

React.js' Virtual DOM

Bildbeschreibung eingeben

PROS

  • Schneller und effizienter "Diff"-Algorithmus
  • Mehrere Frontends (JSX, Hyperskript)
  • Leicht genug, um auf mobilen Geräten zu laufen
  • Viele Akzeptanz und Interesse
  • Kann ohne React verwendet werden (d.h. als eigenständiger Motor)

CONS

  • Vollständige In-Memory-Kopie des DOMs (höherer Speicherverbrauch)
  • Keine Unterscheidung zwischen statischen und dynamischen Elementen

Ember.js' Glimmer

Bildbeschreibung eingeben

PROS

  • Schneller und effizienter Diffing-Algorithmus
  • Unterscheidung zwischen statischen und dynamischen Elementen
  • 100% kompatibel mit Embers API (du bekommst die Vorteile ohne größere Aktualisierungen deines bestehenden Codes)
  • Leichte In-Memory-Repräsentation des DOMs

CONS

  • Soll nur in Ember verwendet werden
  • Nur eine verfügbare Oberfläche

Incremental DOM

Bildbeschreibung eingeben

PROS

  • Verringerte Speicherbelegung
  • Einfache API
  • Integriert sich leicht in viele Frontends und Frameworks (von Anfang an als Template-Engine-Backend gedacht)

CONS

  • Nicht so schnell wie andere Bibliotheken (das ist umstritten, siehe die Benchmarks unten)
  • Weniger Akzeptanz und Nutzung in der Community

36voto

Sophie Alpert Punkte 133000

Hier ist ein Kommentar des React-Teammitglieds Sebastian Markbåge, der etwas Licht ins Dunkel bringt:

React führt das Diffing am Output durch (der in einem bekannten serialisierbaren Format vorliegt, DOM-Attribute). Dies bedeutet, dass die Quelldaten in jedem Format vorliegen können. Es können unveränderliche Datenstrukturen und Zustände innerhalb von Closures sein.

Das Angular-Modell erhält die referenzielle Transparenz nicht aufrecht und ist daher grundsätzlich veränderbar. Sie verändern das bestehende Modell, um Änderungen nachzuverfolgen. Was ist, wenn Ihre Datenquelle unveränderliche Daten oder eine neue Datenstruktur jedes Mal ist (zum Beispiel eine JSON-Antwort)?

Dirty Checking und Object.observe funktionieren nicht im Closure-Bereichsstatus.

Diese beiden Dinge sind offensichtlich sehr einschränkend für funktionale Muster.

Zusätzlich wird es bei wachsender Modellkomplexität immer teurer, Dirty Tracking zu betreiben. Wenn Sie jedoch wie bei React das Diffing nur im visuellen Baum durchführen, wächst es nicht so stark an, da die Menge der Daten, die Sie zu einem bestimmten Zeitpunkt auf dem Bildschirm anzeigen können, durch die Benutzeroberflächen begrenzt ist. Der obige Link von Pete deckt weitere Leistungspräferenzen ab.

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

0voto

Mridul Das Punkte 1

In React hat jeder Ihrer Komponenten einen Status. Dieser Zustand ist ähnlich wie ein beobachtbares Objekt, das Sie möglicherweise in Knockout oder anderen MVVM-Style-Bibliotheken finden. Im Wesentlichen weiß React, wann die Szene neu gerendert werden muss, weil es beobachten kann, wann diese Daten sich ändern. Das Überprüfen auf Änderungen ist langsamer als Beobachtbare, da Sie die Daten in regelmäßigen Abständen überprüfen und alle Werte in der Datenstruktur rekursiv prüfen müssen. Im Vergleich dazu signalisiert das Setzen eines Werts im Zustand einem Zuhörer, dass sich ein Zustand geändert hat, sodass React einfach auf Änderungsereignisse im Zustand hören und Neuzeichnungen in die Warteschlange stellen kann. Der virtuelle DOM wird für eine effiziente Neuzeichnung des DOM verwendet. Dies hat nicht wirklich etwas mit dem Überprüfen Ihrer Daten zu tun. Sie könnten den virtuellen DOM mit oder ohne Überprüfung auf Dirty-Daten neu zeichnen. Sie haben Recht, dass es einige Overheads bei der Berechnung des Unterschieds zwischen zwei virtuellen Bäumen gibt, aber der virtuelle DOM-Unterschied besteht darin, zu verstehen, was im DOM aktualisiert werden muss, und nicht darin, ob Ihre Daten geändert wurden. Tatsächlich ist der Unterschiedsalgorithmus selbst ein Dirty-Checker, aber er wird verwendet, um festzustellen, ob der DOM schmutzig ist.

Unser Ziel ist es, den virtuellen Baum nur neu zu zeichnen, wenn sich der Zustand ändert. Daher ist die Verwendung eines Beobachtbaren zur Überprüfung, ob sich der Zustand geändert hat, ein effizienter Weg, um unnötige Neuzeichnungen zu verhindern, die viele unnötige Baumunterschiede verursachen würden. Wenn sich nichts geändert hat, tun wir nichts.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X