Inhaltsverzeichnis
1. Was ist ein Diff-Algorithmus?
Zunächst muss klar sein, dass Diff dies tut treten nur während der React-Update-Phase auf. Anwendung des Algorithmus
Wann Entwickeln Sie Komponenten basierend auf Baumunterschieden:
Heim Web-Frontend js-Tutorial Was ist der Diff-Algorithmus in React? Strategie und Implementierung des Diff-Algorithmus

Was ist der Diff-Algorithmus in React? Strategie und Implementierung des Diff-Algorithmus

Sep 28, 2018 pm 05:27 PM
html html5 javascript react.js 前端

Der Inhalt dieses Artikels befasst sich mit der Frage, was der Diff-Algorithmus in React ist. Die Strategie und Implementierung des Diff-Algorithmus haben einen gewissen Referenzwert. Freunde in Not können sich darauf beziehen.

1. Was ist ein Diff-Algorithmus?

  • Traditioneller Diff: Der Diff-Algorithmus ist der Differenzsuchalgorithmus; für die HTML-DOM-Struktur ist er der Unterschied Suche nach Baumalgorithmus; die zeitliche Komplexität der Berechnung der Differenz zwischen zwei Bäumen ist offensichtlich zu teuer und es ist für React unmöglich, diesen traditionellen Algorithmus zu übernehmen; 🎜>

    React Diff:
  • Wie bereits erwähnt, nutzt React die virtuelle DOM-Technologie, um das reale DOM abzubilden, also die Differenzsuche von React Der Diff-Algorithmus dient im Wesentlichen dem Vergleich zweier JavaScript-Objektunterschiede.
    • basiert auf drei Strategien:

    • Cross- Ebenenbewegungsoperation von DOM-Knoten in der Web-Benutzeroberfläche Sehr klein und kann ignoriert werden. (Baumunterschied)
  1. Zwei Komponenten mit derselben Klasse erzeugen ähnliche Baumstrukturen, und zwei Komponenten mit unterschiedlichen Klassen erzeugen unterschiedliche Baumstrukturen (Komponentenunterschied)

  2. Eine Gruppe untergeordneter Knoten auf derselben Ebene kann durch eine eindeutige ID unterschieden werden. (Element Diff)

  3. 2. Interpretation des React Diff-Algorithmus

Zunächst muss klar sein, dass Diff dies tut treten nur während der React-Update-Phase auf. Anwendung des Algorithmus

  • React-Update-Mechanismus:

Was ist der Diff-Algorithmus in React? Strategie und Implementierung des Diff-AlgorithmusStrategiediagramm zur Optimierung des React Diff-Algorithmus:

Was ist der Diff-Algorithmus in React? Strategie und Implementierung des Diff-AlgorithmusReact Die Aktualisierungsphase bestimmt den ReactElement-Typ und führt verschiedene Vorgänge aus. Zu den ReactElement-Typen gehören drei Typen: Text, Dom und Komponenten.

  • Die Aktualisierungsverarbeitungsmethode von Jeder Elementtyp:

  • Die Aktualisierung benutzerdefinierter Elemente dient hauptsächlich der Aktualisierung der gerenderten Knoten, und der Ladenbesitzer überlässt es der entsprechenden Komponente der gerenderten Knoten, die Aktualisierungen zu verwalten .
    • Das Aktualisieren des Textknotens ist sehr einfach. Aktualisieren Sie einfach die Kopie direkt.

    • Die Aktualisierung der Grundelemente des Browsers gliedert sich in zwei Teile:

    • Attribute aktualisieren, vergleichen Sie das Vorherige und nach den Attributen unterschiedlich, teilweise Aktualisierung. Und behandeln Sie spezielle Eigenschaften, wie z. B. die Ereignisbindung.
  1. Die Aktualisierung von untergeordneten Knoten dient hauptsächlich dazu, die Differenzobjekte zu finden. Beim Auffinden der Differenzobjekte verwenden wir auch die obige „shouldUpdateReact“-Komponente, um zu beurteilen, ob sie direkt aktualisiert werden kann Rufen Sie die Aktualisierung des untergeordneten Knotens auf, wodurch das Differenzobjekt ebenfalls rekursiv gefunden wird. Das Löschen früherer Objekte oder das Hinzufügen neuer Objekte kann nicht direkt aktualisiert werden. Betreiben Sie dann das DOM-Element (Position ändern, löschen, hinzufügen usw.) entsprechend dem Differenzobjekt.

Tatsächlich wird der Diff-Algorithmus nur während des DOM-Elementaktualisierungsprozesses in der React-Aktualisierungsphase aufgerufen. Warum sagen Sie das? ?
  • 1. Wenn der Texttyp aktualisiert wird
  • und der Inhalt unterschiedlich ist, wird er direkt aktualisiert und ersetzt, ohne den komplexen Diff-Algorithmus aufzurufen:
 ReactDOMTextComponent.prototype.receiveComponent(nextText, transaction) {
    //与之前保存的字符串比较
    if (nextText !== this._currentElement) {
      this._currentElement = nextText;
      var nextStringText = '' + nextText;
      if (nextStringText !== this._stringText) {
        this._stringText = nextStringText;
        var commentNodes = this.getHostNode();
        // 替换文本元素
        DOMChildrenOperations.replaceDelimitedText(
          commentNodes[0],
          commentNodes[1],
          nextStringText
        );
      }
    }
  }
Nach dem Login kopieren

2. Für benutzerdefinierte Komponentenelemente:

class Tab extends Component {
    constructor(props) {
        super(props);
        this.state = {
            index: 1,
        }
    }
    shouldComponentUpdate() {
        ....
    }
    render() {
        return (
            <p>
                </p><p>item1</p>
                <p>item1</p>
            
        )
    }
    
}
Nach dem Login kopieren

Was eine Komponente ist, kann man sagen ist nur ein Verpackungscontainer einer HTML-Struktur und hat die Fähigkeit, den Status dieser HTML-Struktur zu verwalten.

  • Zum Beispiel ist die oben erwähnte Tab-Komponente: ihr wesentlicher Inhalt Die von der Renderfunktion zurückgegebene HTML-Struktur und die sogenannte Tab-Klasse sind der Verpackungscontainer dieser HTML-Struktur (kann als Verpackungsbox verstanden werden).

  • Wie Sie sehen können Im Diagramm des React-Rendering-Mechanismus wird die benutzerdefinierte Komponente schließlich mit der React Diff-Optimierungsstrategie 1 kombiniert (Zwei Komponenten verschiedener Klassen haben unterschiedliche Strukturen)

  • 3 🎜>
ReactDOMComponent.prototype.receiveComponent = function(nextElement, transaction, context) {
    var prevElement = this._currentElement;
    this._currentElement = nextElement;
    this.updateComponent(transaction, prevElement, nextElement, context);
}

ReactDOMComponent.prototype.updateComponent = function(transaction, prevElement, nextElement, context) {
    //需要单独的更新属性
    this._updateDOMProperties(lastProps, nextProps, transaction, isCustomComponentTag);
    //再更新子节点
    this._updateDOMChildren(
      lastProps,
      nextProps,
      transaction,
      context
    );

    // ......
}
Nach dem Login kopieren

Dabei wird der Diff-Algorithmus intern in der _updateDOMChildren-Methode aufgerufen.

  • 3. Implementierung des Diff-Algorithmus in React

    _updateChildren: function(nextNestedChildrenElements, transaction, context) {
        var prevChildren = this._renderedChildren;
        var removedNodes = {};
        var mountImages = [];
    
        // 获取新的子元素数组
        var nextChildren = this._reconcilerUpdateChildren(
          prevChildren,
          nextNestedChildrenElements,
          mountImages,
          removedNodes,
          transaction,
          context
        );
    
        if (!nextChildren && !prevChildren) {
          return;
        }
    
        var updates = null;
        var name;
        var nextIndex = 0;
        var lastIndex = 0;
        var nextMountIndex = 0;
        var lastPlacedNode = null;
    
        for (name in nextChildren) {
          if (!nextChildren.hasOwnProperty(name)) {
            continue;
          }
          var prevChild = prevChildren && prevChildren[name];
          var nextChild = nextChildren[name];
          if (prevChild === nextChild) {
            // 同一个引用,说明是使用的同一个component,所以我们需要做移动的操作
            // 移动已有的子节点
            // NOTICE:这里根据nextIndex, lastIndex决定是否移动
            updates = enqueue(
              updates,
              this.moveChild(prevChild, lastPlacedNode, nextIndex, lastIndex)
            );
    
            // 更新lastIndex
            lastIndex = Math.max(prevChild._mountIndex, lastIndex);
            // 更新component的.mountIndex属性
            prevChild._mountIndex = nextIndex;
    
          } else {
            if (prevChild) {
              // 更新lastIndex
              lastIndex = Math.max(prevChild._mountIndex, lastIndex);
            }
    
            // 添加新的子节点在指定的位置上
            updates = enqueue(
              updates,
              this._mountChildAtIndex(
                nextChild,
                mountImages[nextMountIndex],
                lastPlacedNode,
                nextIndex,
                transaction,
                context
              )
            );
    
    
            nextMountIndex++;
          }
    
          // 更新nextIndex
          nextIndex++;
          lastPlacedNode = ReactReconciler.getHostNode(nextChild);
        }
    
        // 移除掉不存在的旧子节点,和旧子节点和新子节点不同的旧子节点
        for (name in removedNodes) {
          if (removedNodes.hasOwnProperty(name)) {
            updates = enqueue(
              updates,
              this._unmountChild(prevChildren[name], removedNodes[name])
            );
          }
        }
      }
    Nach dem Login kopieren
    Entwicklungsvorschläge basierend auf Diff

Wann Entwickeln Sie Komponenten basierend auf Baumunterschieden:

  • , achten Sie darauf, die DOM-Struktur stabil zu halten, dh die DOM-Struktur so wenig wie möglich dynamisch zu manipulieren, insbesondere mobil Operationen.

  1. Wenn die Anzahl der Knoten zu groß ist oder die Seite zu oft aktualisiert wird, wird die Seitenverzögerung deutlicher.

  2. Zu diesem Zeitpunkt können Sie Knoten über CSS ausblenden oder anzeigen, anstatt DOM-Knoten tatsächlich zu entfernen oder hinzuzufügen.

  3. Basierend auf Komponentenunterschied
  4. :
  1. Achten Sie auf die Verwendung von ShouldComponentUpdate(), um unnötige Aktualisierungen von Komponenten zu reduzieren.

  2. Ähnliche Strukturen sollten so weit wie möglich in Komponenten gekapselt werden, was nicht nur die Codemenge reduziert, sondern auch den Leistungsverbrauch von Komponentenunterschieden verringert.

  • Basierend auf Elementdiff:

    1. Versuchen Sie bei Listenstrukturen, so etwas wie zu minimieren Das Hinzufügen des letzten Knotens an den Kopf der Liste wirkt sich in gewissem Maße auf die Renderleistung von React aus, wenn die Anzahl der Knoten zu groß ist oder die Aktualisierungsvorgänge zu häufig sind.

    Das obige ist der detaillierte Inhalt vonWas ist der Diff-Algorithmus in React? Strategie und Implementierung des Diff-Algorithmus. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

    Erklärung dieser Website
    Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn

    Heiße KI -Werkzeuge

    Undresser.AI Undress

    Undresser.AI Undress

    KI-gestützte App zum Erstellen realistischer Aktfotos

    AI Clothes Remover

    AI Clothes Remover

    Online-KI-Tool zum Entfernen von Kleidung aus Fotos.

    Undress AI Tool

    Undress AI Tool

    Ausziehbilder kostenlos

    Clothoff.io

    Clothoff.io

    KI-Kleiderentferner

    Video Face Swap

    Video Face Swap

    Tauschen Sie Gesichter in jedem Video mühelos mit unserem völlig kostenlosen KI-Gesichtstausch-Tool aus!

    Heiße Werkzeuge

    Notepad++7.3.1

    Notepad++7.3.1

    Einfach zu bedienender und kostenloser Code-Editor

    SublimeText3 chinesische Version

    SublimeText3 chinesische Version

    Chinesische Version, sehr einfach zu bedienen

    Senden Sie Studio 13.0.1

    Senden Sie Studio 13.0.1

    Leistungsstarke integrierte PHP-Entwicklungsumgebung

    Dreamweaver CS6

    Dreamweaver CS6

    Visuelle Webentwicklungstools

    SublimeText3 Mac-Version

    SublimeText3 Mac-Version

    Codebearbeitungssoftware auf Gottesniveau (SublimeText3)

    Tabellenrahmen in HTML Tabellenrahmen in HTML Sep 04, 2024 pm 04:49 PM

    Anleitung zum Tabellenrahmen in HTML. Hier besprechen wir verschiedene Möglichkeiten zum Definieren von Tabellenrändern anhand von Beispielen für den Tabellenrand in HTML.

    HTML-Rand links HTML-Rand links Sep 04, 2024 pm 04:48 PM

    Anleitung zum HTML-Rand links. Hier besprechen wir einen kurzen Überblick über HTML margin-left und seine Beispiele sowie seine Code-Implementierung.

    Verschachtelte Tabelle in HTML Verschachtelte Tabelle in HTML Sep 04, 2024 pm 04:49 PM

    Dies ist eine Anleitung für verschachtelte Tabellen in HTML. Hier diskutieren wir anhand der entsprechenden Beispiele, wie man eine Tabelle innerhalb der Tabelle erstellt.

    HTML-Tabellenlayout HTML-Tabellenlayout Sep 04, 2024 pm 04:54 PM

    Leitfaden zum HTML-Tabellenlayout. Hier besprechen wir die Werte des HTML-Tabellenlayouts zusammen mit den Beispielen und Ausgaben im Detail.

    HTML-Eingabeplatzhalter HTML-Eingabeplatzhalter Sep 04, 2024 pm 04:54 PM

    Leitfaden für HTML-Eingabeplatzhalter. Hier besprechen wir die Beispiele für HTML-Eingabeplatzhalter zusammen mit den Codes und Ausgaben.

    Text in HTML verschieben Text in HTML verschieben Sep 04, 2024 pm 04:45 PM

    Anleitung zum Verschieben von Text in HTML. Hier besprechen wir eine Einführung, wie Marquee-Tags funktionieren, mit Syntax und Beispielen für die Implementierung.

    HTML-geordnete Liste HTML-geordnete Liste Sep 04, 2024 pm 04:43 PM

    Leitfaden zur HTML-geordneten Liste. Hier besprechen wir auch die Einführung von HTML-geordneten Listen und Typen sowie deren Beispiele

    HTML-Onclick-Button HTML-Onclick-Button Sep 04, 2024 pm 04:49 PM

    Anleitung zum HTML-OnClick-Button. Hier diskutieren wir deren Einführung, Funktionsweise, Beispiele und Onclick-Events in verschiedenen Veranstaltungen.

    See all articles