Der beste Weg, um mit dem DOM zu arbeiten

Während ich über Solid schrieb , hatte ich die Möglichkeit, die Anzahl der Versuche zur Optimierung der Leistung in Diagrammen (Benchmarks) abzuschätzen.

DOM ist eine Front-End-Engpassentwicklung. Unterschiedliche Lösungen können zu ähnlichen Ergebnissen führen. Jede Woche erscheinen neue Bibliotheken, die die besten der vorherigen enthalten, um die perfekte Kombination zu erzielen. Nach einiger Zeit laufen meine Augen vor einer solchen Vielfalt von Lösungen davon.

Verstehe mich nicht falsch. Ich mag es, wenn neue Ideen zum Leben erweckt werden, aber alle haben Mängel und manchmal einen Verlust an Bequemlichkeit oder Produktivität. Ich verstehe die Konsequenzen einer solchen Entscheidung, möchte aber meine Beobachtungen teilen.

Was ist der schnellste Weg, um mit dem DOM zu arbeiten:

  • Virtueller Dom
  • Verschlagwortet mit Vorlagenliterale
  • Feinkörnige Observable

Vergleich


JS Frameworks Benchmark ist das beste Open Source-Projekt zum Vergleichen der Leistung von JavaScript-UI-Frameworks. Es ist besser, Tests lokal durchzuführen, als offizielle Ergebnisse zu verwenden. Die Ergebnisse können je nach Maschine variieren. Da ich auf einem schwachen Computer teste, sinkt die Leistung spürbar.

Ich werde die besten Ansätze beim Rendern eines DOM-Baums verfolgen, um die Redundanz bestimmter Lösungen zu veranschaulichen. Ich werde dies mit der Fähigkeit von Solid tun, verschiedene Rendering-Optionen zu unterstützen, um Kosten zu verursachen, wenn sich die Variablen ändern, und dies mit ähnlichen Ergebnissen aus anderen Frameworks zu vergleichen. Schauen wir sie uns an.

Feststoffsorten:

  • solid - Version des Frameworks mit ES2015-Proxy-Setter zusätzlich zu den in geklonten DOM-Knotenvorlagen integrierten Änderungsverfolgungsfunktionen. Dies wird durch Vorkompilieren von JSX-Vorlagen (Code) erreicht.
  • Solid-Signale - Diese Version ist dieselbe wie die vorherige, jedoch werden anstelle von Proxys Rohsignale verwendet. Dies erschwert die Verwendung der Bibliothek, aber am Ende erhalten wir ein kleineres Paket und eine bessere Leistung (Code).
  • Dauerlicht - Diese Version verwendet zur Laufzeit keine JSX-Vorkompilierung (Code).
  • solid-h - Diese Version verwendet HyperScript, um "document.createElement" im laufenden Betrieb zu erstellen. Der Rest verwendet dieselbe Implementierung wie Solid (Code).

Andere Bibliotheken:

  • domc — -, DOM DSL (domain specific language) HTML, index.html (Code)
  • surplus — JSX `document.createElement`. Solid (Code)
  • ivi — Inferno, DOM. HyperScript Helpers-esque (Code)
  • lit-html — , c . Tagged Template Literals DOM- (Code)
  • inferno ist der schnellste React-Klon und eine der schnellsten virtuellen DOM-Bibliotheken. Verwendet spezielle JSX-Anweisungen für beste Leistung (Code)

Einige Ihrer bevorzugten Frameworks sind möglicherweise nicht hier, aber diese Liste zeigt optimierte Versionen aller Techniken an, die Sie in den beliebtesten Frameworks sehen werden. Sie können es als Indikator betrachten, um die maximalen Funktionen Ihrer Bibliothek zu bewerten. Wenn Sie die Leistung gängiger Frameworks vergleichen möchten, empfehle ich diese Tabelle.

Zum Vergleich möchte ich Web Assembly hinzufügen. Leider waren WASM-Datensätze zum Zeitpunkt dieses Schreibens eine Vanille-Implementierung ohne Abstraktionen auf hoher Ebene. (Später fügten sie dem Framework wasm-bindgen hinzu - ca. Übersetzer)

Ergebnisse


HyperScript (Inferno, ivi, solid-h)


HyperScript zeigt Markup als Zusammensetzung von Funktionen an (wie h oder React.createElement). Zum Beispiel:

h('div', {id: 'my-element'}, [
  h('span', 'Hello'),
  h('span', 'John')
])

Virtuelle DOM-Frameworks haben diese Eigenschaft. Selbst wenn sie JSX oder andere DSL-Template-Engines verwenden, werden sie unter der Haube immer noch in elementweise Rendermethoden konvertiert. Dies wird verwendet, um einen virtuellen DOM-Baum für jeden Renderzyklus zu erstellen. Wie hier gezeigt, können die gerenderten Funktionen jedoch verwendet werden, um ein reaktives Abhängigkeitsdiagramm zu erstellen, wie im Fall von Solid.



Wie Sie sehen können, sind Bibliotheken mit einem virtuellen DOM viel schneller. Solide verlieren an Leistung aufgrund der übermäßigen Erstellung eines reaktiven Graphen. Beachten Sie den Unterschied in den Benchmarks Nr. 1, Nr. 2, Nr. 7, Nr. 8, Nr. 9.



Die Erinnerung ist weniger überzeugend. Inferno und diese Version von Solid zeigen ungefähr das gleiche Ergebnis. Während ivi mehr Speicher verwendet.
, Solid, , VDOM. Solid , DOM, DOM. Solid JSX DOM . , . Solid fine grained evaluation . - .

Reaktive Update-Tracking-Frameworks zeigen beim Aktualisieren von Zeilen bessere Ergebnisse. Diese Grafik würde die Popularität von VDOM in den letzten Jahren erklären. Es genügt zu sagen, dass Sie, wenn Sie HyperScript mit diesem Update verwenden, besser zu Virtual DOM wechseln sollten.

Zeichenfolgenvorlagen (domc, lit-html, solid-lit)


Jede Bibliothek hier hat etwas gemeinsam. Sie werden basierend auf Klonelementvorlagen gerendert, zur Laufzeit ausgeführt und verwenden kein VDOM. Aber sie haben immer noch Unterschiede. DomC und lit-html verwenden Top-Down-Unterschiede ähnlich wie Virtual DOM, während Solid ein reaktives Diagramm verwendet. Lit-html teilt Vorlagen in Teile. DomC und Solid kompilieren die Vorlage zur Laufzeit in separate Pfade und aktualisieren diese.



Diese Kategorie hat das breiteste Leistungsspektrum. DomC ist am schnellsten und lit-html am langsamsten. Solid Lit ist in der Mitte. DomC zeigt, dass die Einfachheit des Codes zur besten Leistung führt.

DomC sackt nur in Abschnitt 4 ab, da es die Differenz der Knoten berechnet, was mit zunehmender Tiefe komplizierter wird. Es ist ziemlich schnell, aber Sie müssen die Ergebnisse für Big Data validieren.

Solid Lit ist produktiver als Solid HyperScript. Durch die sofortige Kompilierung zur Laufzeit werden die Nachteile der Erstellung eines reaktiven Diagramms beseitigt, sodass das Framework ivi, die schnellste VDOM-Bibliothek, einholen kann (siehe die vollständige Tabelle am Ende des Artikels).



DomC zeigte gute Ergebnisse beim Speicherverbrauch. Dies geschah aufgrund des Klonens der Vorlagenelemente. Es ist bemerkenswert, dass die Codegenerierung zur Laufzeit im Vergleich zur Kompilierung in der Erstellungsphase nur einen minimalen Leistungsaufwand verursachen kann. Vielleicht ist dies ein unfairer Vergleich für lit-html, da das Framework diese Technik nicht verwendet. Es ist jedoch fair zu sagen, dass lit-html oder ähnliche Bibliotheken wie hyperHTML oder leichterHTML nicht der beste Weg sind, um Tagged Template Literals zu implementieren. Und Sie können auch zur Laufzeit ohne VDOM gute Ergebnisse erzielen.

Vorkompiliertes JSX (Solid, Solid-Signale, Überschuss)


Diese Bibliotheken verwenden JSX, das in der Erstellungsphase in ein DOM oder einen reaktiven Graphen kompiliert wird. Vorlagen können alles sein, aber JSX bietet einen sauberen Syntaxbaum, der die Entwicklererfahrung verbessert.



Diese Gruppe hat ähnliche Ergebnisse, aber der Unterschied ist sehr wichtig. Alle drei verwenden dieselbe Bibliothek, um den Status von S.js zu verwalten . Anhand des Beispiels "Feste Signale" können Sie sehen, dass Tracking-Funktionen beim Klonen von Vorlagenelementen eine höhere Leistung bieten. Die Standardimplementierung von Solid wird mit ES2015 Proxies überladen, wodurch sich das Ergebnis in allen Diagrammen verschlechtert. Surplus verwendet "document.createElement", wodurch die Leistung bei Tests beeinträchtigt wird, bei denen die Zeilen 1, 2, 7 und 8 erstellt werden.



Der Speicherverbrauch hat ähnliche Ergebnisse. In diesem Fall sind Proxys komplexer als das Klonen von Vorlagenelementen.

Die Schlussfolgerung hier ist, dass Proxys die Leistung beeinträchtigen und mehr Bibliotheken Vorlagen klonen sollten. Auf der anderen Seite können Sie einen kleinen Leistungsverlust aufgrund von Proxies als Investition betrachten. Das Solid-Beispiel enthält unter anderem die geringste Menge an Code - nur 66 Zeilen, 13% weniger Leerzeichen als Svelte - eine Bibliothek, die stolz auf ihren Minimalismus ist.

Klassenbester (Domc, Ivi, Solid-Signale, Vanillajs)


Nehmen wir nun die Gewinner in jeder Kategorie und vergleichen sie mit dem brutalen, effektiven, handgeschriebenen Beispiel in Vanille-JavaScript. Jede Implementierung stellt eine der beliebtesten Zustandsverfolgungslösungen dar. Sie können sogar eine Analogie zwischen diesen Bibliotheken und den Big Three ziehen: Solid → Vue, DomC → Angular, ivi → React. Sie erhalten dieses Ergebnis, wenn Sie alles Überflüssige außer dem Rendern entfernen und den 60-200-KB-Code entfernen.



DomC und Solid liegen in Bezug auf die Leistung nahe beieinander, ivi liegt deutlich zurück, aber DomC ist insgesamt schneller. Die Komplexität im Vergleich zu vanillaJS ist deutlich geringer, bei Teilaktualisierungen jedoch weniger effektiv. Nur dieses Kriterium ist nicht indikativ. Jeder, der denkt, dass VDOM langsam ist oder unnötige Komplikationen hat, sollte dies selbst überprüfen.

Die meisten Bibliotheken werden niemals eine solche Leistung erbringen.



DomC ist auch in der Grafik mit Speicher führend. Feinkörniger Feststoff übertrifft VDOM ivi hinsichtlich des Speicherverbrauchs.

Interessanterweise sind diese Bibliotheken unabhängig von der Methode nicht viel schlechter als vanillaJS. Sie sind alle sehr schnell.

Bündelgröße


Abschließend möchte ich auf die Größe des Bundles eingehen. Viele echte Tests konzentrieren sich nur auf diese Metriken. Ja, die Größe des Bundles ist wichtig und steht in direktem Zusammenhang mit der Leistung. Aber was ist der Unterschied? Ich vermute, dass die Komplexität des Codes wichtiger ist als die Größe.



Fazit


Wie üblich sind die Ergebnisse in solchen Grafiken nie vollständig überzeugend. Der Prozess selbst und die Schlussfolgerungen, die wir ziehen, sind wichtig. In diesem Fall sehen wir, dass das DOM selbst ein großer Engpass in Bezug auf die Leistung ist. So sehr, dass es keine eindeutige Technik gibt, um es zu umgehen.


Christoper Lambert als The Highlander

Nein, so einfach ist das nicht. Weder das DOM noch das VDOM sind langsam. Aber ich glaube, dass sie sich gegenseitig wert sind. Ich gebe zu, dass mich die Rhetorik des VDOM Performance React zu diesen Gedanken geführt hat. Die Unkenntnis der Meinungen zu diesem Thema ist wütend.

Die Behauptung, dass VDOM langsam ist, ist auf mangelndes Bewusstsein zurückzuführen. Das Rendern von VDOM und das Berechnen des Zustandsunterschieds ist eine Komplikation im Vergleich dazu, dies nicht zu tun. Aber ist seine Abwesenheit skalierbar? Und wie nimmt man Datenänderungen vor?

Ich sehe, dass es in jeder Regel eine Ausnahme gibt. Im Allgemeinen ist die Vorkompilierung in Kombination mit Feinkörnigkeit in reaktiven Gerüsten die schnellste Lösung. Aber DomC zeigt hohe Leistung ohne es. Native JS-Methoden wie das Klonen von Vorlagenelementen mit markierten Vorlagenliteralen sind möglicherweise die beste Lösung für die Implementierung von lit-html von großen Unternehmen (Google). Dies ist jedoch eines der langsamsten Frameworks in dieser Tabelle und nicht einmal die beste Implementierung dieser Technologien. Svelte gilt als die schnellste Bibliothek in der Community, konnte jedoch nicht einmal eng mit den vorgestellten Lösungen konkurrieren.

Wenn die reaktive Programmierung gewinnt, bedeutet dies nicht, dass alle reaktiven Bibliotheken schnell sind oder dass Metriken alles bedeuten. Trotz des tiefen Vergleichs in diesem Artikel denke ich, dass es in Wirklichkeit schnelle und langsamere Bibliotheken gibt. Selbst wenn wir Supertechnologie finden, werden wir immer noch an ihre Grenzen stoßen.

Testergebnisse aller Bibliotheken in einer Tabelle:


All Articles