In diesem Beitrag geht es nicht um die Vor- und Nachteile von innerHTML
vs. W3C-DOM-Methoden. Das wurde an anderer Stelle gehasht und wiedergewärmt. Stattdessen zeige ich, wie Sie die Verwendung von innerHTML
kombinieren können und DOM-Methoden, um Ihren Code potenziell hundertmal schneller als innerHTML
zu machen allein, wenn mit einer großen Anzahl von Elementen gearbeitet wird.
In einigen Browsern (insbesondere Firefox), obwohl innerHTML
ist im Allgemeinen viel schneller als DOM-Methoden, es verbringt unverhältnismäßig viel Zeit damit, vorhandene Elemente zu löschen, anstatt neue zu erstellen. Wenn wir dies wissen, können wir die Geschwindigkeit des Zerstörens von Elementen durch Entfernen ihrer Eltern mithilfe der Standard-DOM-Methoden mit dem Erstellen neuer Elemente mithilfe von innerHTML
kombinieren . (Diese Technik habe ich während der Entwicklung von RegexPal entdeckt und ist eine der beiden wichtigsten Leistungsoptimierungen. Die andere ist die One-Shot-Markup-Generierung zur Hervorhebung von Übereinstimmungen, wodurch vermieden wird, dass Übereinstimmungen wiederholt oder einzeln referenziert werden müssen.) P>
Der Code:
function replaceHtml(el, html) { var oldEl = typeof el === "string" ? document.getElementById(el) : el; /*@cc_on // Pure innerHTML is slightly faster in IE oldEl.innerHTML = html; return oldEl; @*/ var newEl = oldEl.cloneNode(false); newEl.innerHTML = html; oldEl.parentNode.replaceChild(newEl, oldEl); /* Since we just removed the old element from the DOM, return a reference to the new element, which can be used to restore variable references. */ return newEl; };
Sie können das obige als el = replaceHtml(el, newHtml)
verwenden statt el.innerHTML = newHtml
.
innerHTML ist schon ziemlich schnell ... ist das wirklich gerechtfertigt?
Das hängt davon ab, wie viele Elemente Sie überschreiben. In RegexPal löst jedes Keydown-Ereignis potenziell die Zerstörung und Erstellung von Tausenden von Elementen aus (damit die Syntax- und Match-Hervorhebung funktioniert). In solchen Fällen hat der obige Ansatz enorme positive Auswirkungen. Sogar etwas so Einfaches wie el.innerHTML += str
oder el.innerHTML = ""
könnte eine Leistungskatastrophe sein, wenn das Element, das Sie aktualisieren, einige tausend untergeordnete Elemente hat.
Ich habe eine Seite erstellt, mit der Sie den Leistungsunterschied von innerHTML
einfach testen können und mein replaceHtml
Funktion mit unterschiedlicher Anzahl von Elementen. Probieren Sie es zum Vergleich in einigen Browsern aus. Im Folgenden finden Sie einige Beispiele für typische Ergebnisse von Firefox 2.0.0.6 auf meinem System:
1000 elements... innerHTML (destroy only): 156ms innerHTML (create only): 15ms innerHTML (destroy & create): 172ms replaceHtml (destroy only): 0ms (faster) replaceHtml (create only): 15ms (~ same speed) replaceHtml (destroy & create): 15ms (11.5x faster) 15000 elements... innerHTML (destroy only): 14703ms innerHTML (create only): 250ms innerHTML (destroy & create): 14922ms replaceHtml (destroy only): 31ms (474.3x faster) replaceHtml (create only): 250ms (~ same speed) replaceHtml (destroy & create): 297ms (50.2x faster)
Ich denke die Zahlen sprechen für sich. Vergleichbare Leistungsverbesserungen sind auch in Safari zu sehen. In Opera replaceHtml
ist normalerweise immer noch schneller als innerHTML
, aber mit einem schmaleren Rand. Im IE einfache Verwendung von innerHTML
ist normalerweise schneller als das Mischen mit DOM-Methoden, aber nicht annähernd mit den gleichen Margen, wie Sie oben sehen können. Trotzdem wird die bedingte Kompilierungsfunktion von IE verwendet, um die relativ geringfügige Leistungseinbuße zu vermeiden, indem einfach innerHTML
verwendet wird mit diesem Browser.