Die Rolle des virtuellen DOMZunächst müssen wir wissen, welches Problem durch die Einführung des virtuellen DOM gelöst werden soll. Es löst das Problem der geringen Effizienz bei unseren häufigen direkten DOM-Operationen. Warum ist es so ineffizient, das DOM direkt zu manipulieren? Wenn wir beispielsweise ein Div erstellen, können wir in der Konsole überprüfen, ob dieses Div viele Eigenschaften hat oder erbt. Insbesondere wenn wir JS zum Bedienen von DOM verwenden, ist unser DOM selbst sehr kompliziert und JS-Operationen werden viel Zeit in Anspruch nehmen, aber wir können die DOM-Elemente selbst nicht steuern. Daher löst virtuelles DOM das Problem des JS-Bedienens von DOM , wodurch die Anzahl der DOM-Operationen tatsächlich reduziert wird. Einfache Implementierung eines virtuellen DOMVirtual DOM ist, wie der Name schon sagt, ein Fake-DOM. Unser reales DOM ist auf der Seite gemountet, während sich unser virtuelles DOM im Speicher befindet. Dies erfordert, dass wir den echten DOM in ein Objekt abstrahieren und im Speicher ablegen. Dieses Objekt kann vom folgenden Typ sein: var Element = { tagName: 'div', Requisiten: { Klasse: "Box" }, Kinder: { { tagName: "p", Requisiten: { Klasse: "p1" }, Kinder: ['Ich bin p1'] }, { tagName: "p", Requisiten: { Klasse: "p2" }, Kinder: ['Ich bin p2'] }, { tagName: "p", Requisiten: { Klasse: "p3" }, Kinder: ['Ich bin p3'] }, } } Wenn wir ein solches Objekt konstruieren möchten, können wir einen Konstruktor wie folgt kapseln: Funktion Element(tagName, Requisiten, untergeordnete Elemente) { this.tagName = Tagname this.props = Requisiten this.children = Kinder } Mit diesem Objekt müssen wir diesen virtuellen DOM in den realen DOM umwandeln. Wir können die folgende Methode schreiben: Element.prototype.render = Funktion () { const { tagName, Requisiten, untergeordnete Elemente } = dies var el = document.createElement(tagName) für (Schlüssel in Requisiten) { el.setAttribute(Schlüssel, Requisiten[Schlüssel]) } Kinder.fürJedes((Element) => { const childEl = (Item-Instanz des Elements)? item.render() : document.createTextNode(Element) el.appendChild(KindEl) }) Rückkehr el } Schließlich können wir dieses Objekt erstellen, die Methode render() aufrufen und dann appendChild an den Textkörper anhängen: let virtualDom = neues Element('div', { Klasse: 'box' }, [ neues Element('p', { Klasse: 'p1' }, ['Ich bin p1']), neues Element('p', { Klasse: 'p2' }, ['Ich bin p2']), neues Element('p', { Klasse: 'p3' }, ['Ich bin p3']), ]) lass a = virtualDom.render() Dokument.Body.AnhängenKind(a) Diff-AlgorithmusLassen Sie uns zunächst die Rolle des Diff-Algorithmus verstehen Wenn sich unser virtueller DOM ändert, wird in unserem Speicher ein neuer virtueller DOM generiert. Wenn wir diese neue virtuelle DOM-Struktur direkt verwenden, führt dies zu vielen wiederholten Renderings. Daher wird zu diesem Zeitpunkt die Rolle des Diff-Algorithmus reflektiert. Diff vergleicht die neuen und alten virtuellen DOM-Bäume, findet die Unterschiede, zeichnet sie auf und wendet die aufgezeichneten Unterschiede dann auf den realen DOM-Baum an. Prinzip: Der Diff-Algorithmus führt eine Tiefensuche durch die neuen und alten Bäume durch und fügt jedem Knoten eine eindeutige Kennung hinzu. Dieser Prozess ist in 2 Schritte unterteilt
Die Operationen auf DOM können grundsätzlich in 4 Typen unterteilt werden
Im Folgenden wird dieser Vorgang grob in Form von Pseudocode durchgegangen // Diff-Funktion, vergleiche zwei Bäume Funktion diff(oldTree, newTree) { var patches = {}; // Pseudo-Array, Unterschiede aufzeichnen // Fehlerbeurteilungen für 4 Knotentypen vornehmen dfWork(oldTree, newTree, patches, index) Rückkehr-Patches } Funktion dfWork(alterBaum, neuerBaum, Patches, Index) { lass currentPatch = [] if (1) { // Lösche den Knoten currentPatch.push() } else if (3) { // Ändere den Text des Knotens currentPatch.push() } sonst { // Eigenschaften des Knotens ändern. Untergeordnete Elemente prüfen. // Einen Diff-Algorithmus für die Eigenschaften ausführen und die Änderungen in Patches aufzeichnen. currentPatch.push({ Typ: Patch.PROPS, Eigenschaften: propsPatches }) // Dann müssen Sie einen Diff-Algorithmus auf den untergeordneten Knoten ausführen diffChildren(oldNode.children, newNode.children, index, patches, currentPatch) } } Funktion diffChildren(alteChildren, neueChildren, Index, Patches, aktuellerPatch) { // Diff-Algorithmus auf untergeordneten Knoten ausführen, untergeordnete Knoten durchlaufen, dfWork rekursiv aufrufen und Unterschiede vornehmen, um Patches zu erhalten } // Die Änderungen auf die aktuelle DOM-Baumfunktion anwenden patch(node, patches) { // Knoten ist der alte DOM-Baum, Patch-Änderungen. // Wir werden die Patches durchlaufen und die Knoten den Patches zuordnen. } Funktion applyPatch(Knoten, Patches) { // Da jeder Knoten mehrere Änderungen aufweisen kann, müssen wir auch switch (patches.type) { durchlaufen. Fall REPLACE: // Knoten ersetzen // node.render() brechen; Case REORDER: // Verschieben, löschen und neue untergeordnete Knoten hinzufügen. brechen; Fall-Props: // setzeProps brechen; case TEXT: // Ändere den Knotentext // node.nodeValue brechen; Standard: brechen; } } Referenzdokument: Detaillierte Analyse: So implementieren Sie einen virtuellen DOM-Algorithmus. Autor: livoras, integrierter Quellcode. Dies ist das Ende dieses Artikels über virtuelle DOM- und Diff-Algorithmen in React. Weitere relevante Inhalte zu virtuellen DOM- und Diff-Algorithmen in React finden Sie in früheren Artikeln auf 123WORDPRESS.COM oder in den folgenden verwandten Artikeln. Ich hoffe, Sie werden 123WORDPRESS.COM auch in Zukunft unterstützen! Das könnte Sie auch interessieren:
|
<<: Lösung für den Konflikt zwischen Nginx und Backend-Port
>>: Detaillierte Analyse des binlog_format-Modus und der Konfiguration in MySQL
Der Test wird in der Node.JS-Umgebung bestanden. ...
1. Systemumgebung [root@localhost-Startseite]# ca...
Wie oben gezeigt, sind Füllwerte zusammengesetzte...
Einzeiliger Befehl docker run -d \ -v /share:/hom...
Inhaltsverzeichnis 1. Umweltvorbereitung 2. Ausfü...
VMware-Version: VMware-Workstation-Full-16 VMware...
Während des jüngsten Entwicklungsprozesses handel...
Die Verwendung von CSS-Layouts zum Erstellen von W...
1. Installation Tipp: Derzeit gibt es kein offizi...
Es gibt zwei Möglichkeiten, mit Nginx mehrere Pro...
Bevor Sie diesen Artikel lesen, hoffe ich, dass S...
Da ich immer vscode zur Entwicklung von Front-End...
Vorwort Wie Sie wissen, unterstützt Linux viele D...
Weil ich ein Datenbank-Tutorial habe, das auf SQL...
Dieser Artikel zeichnet das Installationstutorial...