Detaillierte Erläuterung der Strategie des Abstimmungsalgorithmus von React für den Diffing-Algorithmus

Detaillierte Erläuterung der Strategie des Abstimmungsalgorithmus von React für den Diffing-Algorithmus

Algorithmische Strategie

Der Abstimmungsalgorithmus von React tritt hauptsächlich in der Renderphase auf. Der Abstimmungsalgorithmus ist keine spezifische Algorithmusfunktion, sondern bezieht sich auf eine im Abstimmungsprozess angewendete Strategie zur Verbesserung der Leistung beim Erstellen des WorkInProcess-Baums und der Leistung beim Aktualisieren des Dom-Baums, auch als Diffing-Algorithmus bekannt. Bei der Beschreibung des „Diffing“-Algorithmus auf der offiziellen Website von React ist zwar vom „Diffing zweier Bäume“ die Rede, bei der Implementierung des Quellcodes werden jedoch nicht zwei Bäume erstellt und anschließend das Diffing der beiden Bäume von oben nach unten durchgeführt. Dieses Diffing tritt beim Erstellen von untergeordneten Knoten auf. Dabei handelt es sich eigentlich um das Diffing des neu generierten ReactElements und des Fibe-Knotens im aktuellen Baum. Um die Zeitkomplexität des Differenzierungsalgorithmus innerhalb von O(n) zu halten (die Zeitkomplexität der Baumdifferenzierung beinhaltet die Editierdistanz des Baums, siehe hier), wird die folgende Strategie angewendet:

Vergleichen Sie nur Knoten auf derselben Ebene (anscheinend wird dies auf der offiziellen Website nicht erwähnt).

Wenn beim Vergleich einzelner Knoten der aktuelle Knotentyp und der Schlüssel nicht identisch sind, werden die untergeordneten Knoten nicht mehr verglichen, sondern der Knoten und sein gesamter Unterbaum direkt gelöscht und der Knotenbaum gemäß ReactElement neu generiert. Denn React geht davon aus, dass unterschiedliche Komponententypen unterschiedliche Baumstrukturen erzeugen und nicht wiederverwendet werden müssen.

Wenn es sich bei den untergeordneten Knoten um Arrays handelt, können die Knoten anhand des eindeutigen Schlüsselwerts lokalisiert und verglichen werden, sodass sie auch dann, wenn sich die Reihenfolge der untergeordneten Knoten ändert, anhand des Schlüsselwerts wiederverwendet werden können.

Es ist erwähnenswert, dass bei allen Knotenunterschieden der Schlüssel verglichen wird und der Standardwert des Schlüssels null ist. Wenn nicht festgelegt, ist Null immer gleich Null und der Schlüssel wird als identisch betrachtet.

Einzelknoten-Diffing

Wenn ein einzelner Knoten differenziert wird, werden zwei Attributsätze differenziert: fibe.elementType vs. ReactElement.type, fibe.key vs. ReactElement.key. Wenn diese beiden Attributsätze gleich sind, weist der physische Speicherplatz der Datenstruktur die folgende Wiederverwendungslogik auf (weitere Informationen finden Sie im Quellcode der Funktion reconcileSingleElement):

  1. Wenn der aktuelle Fibe über einen alternativen Knoten verfügt (was bedeutet, dass dieser Fibe-Knoten zuvor an der Abstimmung teilgenommen hat), wird der physische Speicherplatz des alternativen Knotens wiederverwendet. Andernfalls muss der aktuelle Fibe-Knoten geklont werden, um einen neuen physischen Speicherplatz zu belegen.
  2. Die entsprechende Instanz oder Dom wird wiederverwendet
  3. Der untergeordnete Baum unter der aktuellen Faser wird ebenfalls direkt gemountet (er wird im nächsten Schritt beim Rekursieren untergeordneter Knoten verwendet).

Wenn einer der beiden Attributsätze nicht gleich ist:

  • fibe wird basierend auf ReactElement neu erstellt
  • Die entsprechende Instanz und der Dom werden ebenfalls neu erstellt
  • Löschen Sie alle untergeordneten Bäume.

Wenn das generierte ReactElement ein einzelner Knoten ist, der entsprechende aktuelle Baum jedoch mehrere Knoten hat, wird nacheinander gesucht, ob eine Übereinstimmung vorliegt. Wenn eine Übereinstimmung gefunden wird, werden die anderen gelöscht; wenn keine Übereinstimmung gefunden wird, werden alle gelöscht. Beispielsweise verfügt die Komponente „Counter“ über die folgende Logik: Wenn die Anzahl der Klicks größer als 10 ist, wird die Klickschaltfläche ausgeblendet. Beim 10. Mal wird der Span-Knoten wiederverwendet.

Klasse Counter erweitert React.Component {
    Zustand={
        Anzahl: 0
    }
    Anzahl hinzufügen = ()=>{
        const count = dieser.Zustand.count+1;
        dies.setState({Anzahl})
    }
    KomponenteDidUpdate(){
        console.log("aktualisiert")
    }
    machen(){
        gibt diesen Statuszähler < 10 zurück? [
            <button onClick={this.addCount}>Klick</button>
            <span>Anzahl der Klicks: {this.state.count}</span>
        ]:<span>Anzahl der Klicks: {this.state.count}</span>;
    }
}

Array-Knoten-Diffing

Beim Differenzieren von Array-Knoten ist der Vorgang komplizierter: (den Quellcode finden Sie in der Funktion „reconcileChildrenArray“).

Dazwischen gibt es zwei wichtige Durchläufe. Der erste ist ein Durchlauf nach Index, bei dem der neue und der alte Knoten nacheinander verglichen werden und der Durchlauf sofort unterbrochen wird, wenn eine Nichtübereinstimmung der Schlüsselwerte auftritt. Beim zweiten Durchlauf wird für die verbleibenden alten Knoten eine „Schlüssel-Knoten“-Zuordnungstabelle erstellt, die verbleibenden neuen Knoten werden durchlaufen und die alten Knoten zum Vergleichen gemäß dem Schlüsselwert in der Tabelle gesucht. Nachfolgend werden die Zuordnung und der Vergleich neuer und alter Knoten in drei Fällen beschrieben.

Anforderungen für die Verwendung von Schlüsselwerten

Aus der Perspektive der Unterscheidung einzelner Knoten und Array-Knoten wird der Schlüsselwert hauptsächlich verwendet, um die Neuerstellung zu reduzieren. Um sicherzustellen, dass beim Diffing eine Übereinstimmung zwischen den neuen und alten Knoten möglich ist, sollten bei der Verwendung von Schlüsselwerten folgende Punkte beachtet werden:

  1. Es muss stabil sein. Wenn sich der Schlüsselwert jedes Mal ändert (z. B. wenn eine Zufallszahl verwendet wird), stimmen die neuen und alten Abschnitte beim Diffing nicht überein, was zu einer großen Anzahl neuer Erstellungen führt.
  2. Er muss eindeutig sein. Wenn der Schlüsselwert nicht eindeutig ist, wird er beim Erstellen der Map-Tabelle „Schlüssel - Knoten“ übersehen und verwechselt, was zu Seitenaktualisierungsfehlern führt.

Für einen einzelnen Knoten wird der Schlüsselwert auch beim Differenzieren verwendet. Denken Sie nicht, dass er nutzlos ist, und legen Sie ihn nicht nach dem Zufallsprinzip fest. Es gibt auch einige nicht standardmäßige Verwendungen, bei denen Schlüsselwerte für einen einzelnen Knoten verwendet werden, um die Zerstörung und Rekonstruktion von Komponenten zu erreichen. Diese Verwendung entspricht jedoch nicht dem Designkonzept von React.

Beispielsweise gibt es eine Protokollkomponente, die Protokolldaten intern abruft und keine externen Datenabhängigkeiten aufweist . Wenn die Anforderungen jedoch iteriert werden, wird derselben Seite ein Genehmigungsvorgang hinzugefügt. Nach der Genehmigung werden dem Backend neue Protokolldaten hinzugefügt. Zu diesem Zeitpunkt möchten Sie, dass die Front-End-Seite die neu hinzugefügten Protokolldaten in Echtzeit anzeigt, und Sie müssen die Protokollkomponente auslösen, um die Daten erneut abzurufen. Wenn Sie das Problem nicht mit der Methode zum Hochstufen von Daten lösen können, können Sie der Komponente einen zufälligen Schlüssel zuweisen. Wenn der Genehmigungsvorgang abgeschlossen ist, ändern Sie den Schlüsselwert und die Komponente wird neu erstellt. Allerdings ist der Mehraufwand bei dieser Methode sehr hoch und der gesamte Komponentenbaum wird zerstört und neu aufgebaut. Stattdessen können auch andere Lösungen verwendet werden. Sie können beispielsweise einen Verweis für die Komponente angeben. Wenn die Genehmigung abgeschlossen ist, rufen Sie über den Verweis die Aktualisierungsfunktion der Komponente auf, um die Daten erneut abzurufen und die Komponente zu aktualisieren.

Bei Array-Knoten spielt der Schlüsselwert vor allem dann eine Schlüsselrolle, wenn die Position des untergeordneten Knotens stark von der des anderen abweicht . Bei gewöhnlichen Hinzufügungen und Löschungen am Ende kann die erste Indexdurchquerung die Übereinstimmung abschließen, ohne dass eine zweite Schlüsselzuordnungsdurchquerung durchgeführt wird. Da das Schlüssel-Wert-Paar „stabil“ und „eindeutig“ sein muss, verlangt das Frontend im Allgemeinen vom Backend, eine eindeutige Kennung für die Listendaten bereitzustellen. Für die Aggregationsschnittstelle bedeutet dies zusätzliche Arbeit für das Backend. In diesem Fall können Sie zunächst die sich ändernden Eigenschaften der Daten verstehen und dann entscheiden, ob Sie den Schlüssel wirklich festlegen müssen.

Für die obige Protokollkomponente ist das Protokoll eine Liste. Neu hinzugefügte Protokolle werden in die erste Zeile eingefügt. Wenn der Schlüssel nicht gesetzt ist, müssen grundsätzlich alle untergeordneten Knoten aktualisiert werden. Wenn ein Schlüssel festgelegt ist, muss der Backend-Dienst jedem Protokoll eine „für immer“ eindeutige Kennung, beispielsweise eine ID, hinzufügen. Ich habe einmal einen Fall erlebt, wo die Seitenanzeige beim Aktualisieren der Daten falsch war, weil sich die Eindeutigkeit des Schlüsselwerts geändert hatte.

Dies ist das Ende dieses Artikels über den Abstimmungsalgorithmus (Diffing-Algorithmus) von React. Weitere relevante Inhalte zum Diffing-Algorithmus von React finden Sie in den vorherigen Artikeln von 123WORDPRESS.COM oder in den folgenden verwandten Artikeln. Ich hoffe, dass jeder 123WORDPRESS.COM in Zukunft unterstützen wird!

Das könnte Sie auch interessieren:
  • Detaillierte Analyse des Diff-Algorithmus in React
  • Detaillierte Erklärung des virtuellen DOM und des Diff-Algorithmus in React
  • React Diff-Algorithmus-Quellcodeanalyse
  • Detaillierte Erklärung des DOM DIFF-Algorithmus in der React-Anwendung
  • Eine kurze Diskussion zur Analyse des Diff-Algorithmus aus dem React-Rendering-Prozess
  • Beispielimplementierung des React-Diff-Algorithmus
  • Kennen Sie den Diff-Algorithmus in React?

<<:  So positionieren Sie die Kopfzeile mithilfe des CSS-Sticky-Layouts oben

>>:  So zeigen Sie die Ausführungszeit von SQL-Anweisungen in MySQL an

Artikel empfehlen

Detaillierte Schritte zur Installation von Nginx unter Linux

1. Nginx-Installationsschritte 1.1 Offizielle Web...

Details zu 7 Arten der Komponentenkommunikation in Vue3

Inhaltsverzeichnis 1. Kommunikationsmethode für V...

Über das Problem beim Schreiben von Plugins zum Mounten von DOM in vue3

Im Vergleich zu vue2 verfügt vue3 über ein zusätz...

Inaktive Benutzer nach einem Login-Timeout in Linux automatisch abmelden

Methode 1: Ändern Sie die Datei .bashrc oder .bas...

mysql 5.7.5 m15 winx64.zip Installations-Tutorial

So installieren und konfigurieren Sie mysql-5.7.5...

Installationsprozess von Zabbix-Agent auf Kylin V10

1. Laden Sie das Installationspaket herunter Down...

Ausführliches Tutorial zur Installation und Konfiguration von MySQL 8.0.20

In diesem Artikel finden Sie eine ausführliche An...

Detaillierte Erklärung der Verwendung des Linux-Befehls lsof

lsof (List Open Files) ist ein Tool zum Anzeigen ...

Detaillierte Schritte zur Installation von Nginx unter Linux

1. Nginx-Installationsschritte 1.1 Offizielle Web...

Umfassende Zusammenfassung zu MySQL GTID

Inhaltsverzeichnis 01 Einführung in GTID 02 Wie G...

Verwenden Sie zum Senden des Formulars ein Bild statt einer Schaltfläche.

Code kopieren Der Code lautet wie folgt: <form...

So fügen Sie CentOS7 systemd benutzerdefinierte Systemdienste hinzu

systemd: Das Service-Systemctl-Skript von CentOS ...