render(element, vnodes)
Beschreibung
Rendert ein Template in das DOM.
m.render(document.body, 'hello');
// <body>hello</body>
Signatur
m.render(element, vnodes, redraw)
Argument | Typ | Erforderlich | Beschreibung |
---|---|---|---|
element | Element | Ja | Ein DOM-Element, das der übergeordnete Knoten des Teilbaums sein wird. |
vnodes | Array<Vnode>|Vnode | Ja | Die V-Knoten, die gerendert werden sollen. |
redraw | () -> any | Nein | Ein Callback, der jedes Mal aufgerufen wird, wenn ein Event-Handler im Teilbaum aufgerufen wird. |
returns | Gibt undefined zurück. |
Funktionsweise
Die Methode m.render(element, vnodes)
akzeptiert einen virtuellen DOM-Baum (typischerweise generiert über die m()
Hyperscript-Funktion), generiert einen DOM-Baum und fügt ihn in element
ein. Wenn element
bereits einen DOM-Baum hat, der durch einen vorherigen m.render()
-Aufruf erzeugt wurde, wird vnodes
mit dem vorherigen vnodes
-Baum verglichen (Differenzbildung). Der vorhandene DOM-Baum wird nur dort geändert, wo es nötig ist, um die Änderungen widerzuspiegeln. Unveränderte DOM-Knoten bleiben erhalten.
Wenn Sie das optionale redraw
-Argument übergeben, wird dieses jedes Mal aufgerufen, wenn ein Event-Handler innerhalb des Teilbaums aufgerufen wird. Dies wird von m.mount
und m.redraw
verwendet, um die Autoredraw-Funktionalität zu implementieren. Es wird aber auch für fortgeschrittenere Anwendungsfälle wie die Integration mit externen Frameworks bereitgestellt.
m.render
ist synchron.
Warum Virtual DOM
Es mag ineffizient erscheinen, bei jeder Aktualisierung einen V-Knoten-Baum zu generieren, aber das Erstellen und Vergleichen von JavaScript-Datenstrukturen ist im Vergleich zum Lesen und Ändern des DOM überraschend kostengünstig.
Das Bearbeiten des DOM kann aus mehreren Gründen aufwändig sein. Das abwechselnde Lesen und Schreiben kann die Performance beeinträchtigen, da mehrere Browser-Neuberechnungen in schneller Folge auftreten können. Das Vergleichen virtueller DOM-Bäume ermöglicht es jedoch, Schreibvorgänge zu einer einzigen Neuberechnung zusammenzufassen. Außerdem variieren die Leistungsmerkmale verschiedener DOM-Operationen zwischen den Implementierungen, und es kann schwierig sein, sie für alle Browser zu erlernen und zu optimieren. Beispielsweise hat das Lesen von childNodes.length
in einigen Implementierungen eine Komplexität von O(n); in einigen verursacht das Lesen von parentNode
eine Neuberechnung usw.
Im Gegensatz dazu hat das Durchlaufen einer JavaScript-Datenstruktur ein viel vorhersehbareres und besseres Leistungsprofil, und außerdem ist ein Vnode-Baum so implementiert, dass moderne JavaScript-Engines aggressive Optimierungen wie z. B. Hidden Classes für eine noch bessere Leistung anwenden können.
Unterschiede zu anderen API-Methoden
Die Methode m.render()
wird intern von m.mount()
, m.route()
, m.redraw()
und m.request()
aufgerufen. Sie wird nicht nach Datenstrom-Aktualisierungen aufgerufen.
Anders als bei m.mount()
und m.route()
wird ein über m.render()
gerenderter Vnode-Baum nicht automatisch als Reaktion auf View-Ereignisse, m.redraw()
-Aufrufe oder m.request()
-Aufrufe neu gezeichnet (Auto-Redraw). Es ist ein Low-Level-Mechanismus, der sich für Bibliotheksentwickler eignet, die das Rendering manuell steuern möchten, anstatt sich auf das integrierte Auto-Redraw-System von Mithril.js zu verlassen.
Ein weiterer Unterschied besteht darin, dass die Methode m.render
einen Vnode (oder ein Array von Vnodes) als zweiten Parameter erwartet, während m.mount()
und m.route()
Komponenten erwarten.
Standalone-Verwendung
var render = require("mithril/render")
Der Funktionsumfang des Moduls m.render
ist View-Bibliotheken wie Knockout, React und Vue ähnlich. Es implementiert eine Virtual-DOM-Diffing-Engine mit einem modernen Algorithmus zur Reduzierung des Suchraums und DOM-Recycling, was zu einer erstklassigen Leistung sowohl beim anfänglichen Laden der Seite als auch beim erneuten Rendern (Re-Rendering) führt. Es hat keine Abhängigkeiten von anderen Teilen von Mithril.js, außer der Normalisierung, die über require("mithril/render/vnode")
bereitgestellt wird. Daher kann es als eigenständige Bibliothek verwendet werden.
Obwohl das Rendering-Modul relativ klein ist, ist es voll funktionsfähig und autark. Es unterstützt alles, was Sie erwarten würden: SVG, benutzerdefinierte Elemente und alle gültigen Attribute und Events - ohne seltsame, zwischen Groß- und Kleinschreibung unterscheidende Randfälle oder Ausnahmen. Natürlich unterstützt es auch Komponenten und Lifecycle-Methoden vollständig.
Wenn Sie m.render
als eigenständiges Modul verwenden, kann es nützlich sein, auch die Hyperscript-Funktion
zu importieren, um die Vnodes zu erstellen, die gerendert werden sollen.