JavaScript-Leistung - Dom Reflow - Google-Artikel

Könnte mir jemand beweisen, dass der Rat gegeben wurdeHier Das Entfernen von dom-Elementen vor dem Ändern und anschließenden erneuten Einfügen ist immer schneller (siehe unten).

Zum Beweis möchte ich einige Zahlen sehen. Es ist großartig, dass sie dies recherchieren, aber ich denke, der Artikel ist sehr schwach, ohne Angaben dazu zu machen, was das "Problem" eigentlich ist und wie sich die Lösung in Bezug auf die Geschwindigkeit ändert (wie der Titel des Artikels "Beschleunigen von JavaScript").

Der Artikel....

Out-of-the-Flow-DOM-Manipulation

Mit diesem Muster können mehrere Elemente erstellt und in das DOM eingefügt werden, wodurch ein einzelner Reflow ausgelöst wird. Es wird ein sogenanntes DocumentFragment verwendet. Wir erstellen ein DocumentFragment außerhalb des DOM (so dass es nicht mehr im Fluss ist). Anschließend erstellen wir mehrere Elemente und fügen sie hinzu. Schließlich verschieben wir alle Elemente im DocumentFragment in das DOM, lösen jedoch einen einzelnen Reflow aus. Das Problem

Lassen Sie uns eine Funktion erstellen, die das className-Attribut für alle Anker in einem Element ändert. Wir könnten dies tun, indem wir einfach durch die einzelnen Anker iterieren und ihre href-Attribute aktualisieren. Das Problem ist, dass dies zu einem Reflow für jeden Anker führen kann.

function updateAllAnchors(element, anchorClass) {
  var anchors = element.getElementsByTagName('a');
  for (var i = 0, length = anchors.length; i < length; i ++) {
    anchors[i].className = anchorClass;
  }
}

Die Lösung

Um dieses Problem zu lösen, können wir das Element aus dem DOM entfernen, alle Anker aktualisieren und das Element wieder an der Stelle einfügen, an der es sich befand. Um dies zu erreichen, können wir eine wiederverwendbare Funktion schreiben, die nicht nur ein Element aus dem DOM entfernt, sondern auch eine Funktion zurückgibt, mit der das Element wieder an seiner ursprünglichen Position eingefügt wird.

/**
 * Remove an element and provide a function that inserts it into its original position
 * @param element {Element} The element to be temporarily removed
 * @return {Function} A function that inserts the element into its original position
 **/
function removeToInsertLater(element) {
  var parentNode = element.parentNode;
  var nextSibling = element.nextSibling;
  parentNode.removeChild(element);
  return function() {
    if (nextSibling) {
      parentNode.insertBefore(element, nextSibling);
    } else {
      parentNode.appendChild(element);
    }
  };
}

Jetzt können wir diese Funktion verwenden, um die Anker in einem Element zu aktualisieren, das nicht im Fluss ist, und nur dann einen Reflow auszulösen, wenn wir das Element entfernen und wenn wir das Element einfügen.

function updateAllAnchors(element, anchorClass) {
  var insertFunction = removeToInsertLater(element);
  var anchors = element.getElementsByTagName('a');
  for (var i = 0, length = anchors.length; i < length; i ++) {
    anchors[i].className = anchorClass;
  }
  insertFunction();
}

Antworten auf die Frage(5)

Ihre Antwort auf die Frage