render(element, vnodes)
Descrizione
Renderizza un modello nel DOM.
m.render(document.body, 'hello');
// <body>hello</body>
Firma
m.render(element, vnodes, redraw)
Parametro | Tipo | Obbligatorio | Descrizione |
---|---|---|---|
element | Element | Sì | Un elemento DOM che sarà il nodo padre del sottoalbero |
vnodes | Array<Vnode>|Vnode | Sì | I vnodes da renderizzare |
redraw | () -> any | No | Un callback invocato ogni volta che viene invocato un gestore di eventi nel sottoalbero |
restituisce | Restituisce undefined |
Come funziona
Il metodo m.render(element, vnodes)
riceve un albero DOM virtuale (tipicamente generato tramite la funzione hyperscript m()
), genera un albero DOM e lo monta sull'element
. Se element
ha già un albero DOM montato tramite una precedente chiamata m.render()
, vnodes
viene confrontato con il precedente albero vnodes
e l'albero DOM esistente viene modificato solo dove necessario per riflettere le modifiche. I nodi DOM invariati non vengono modificati in alcun modo.
Se si passa l'argomento opzionale redraw
, esso viene invocato ogni volta che un gestore di eventi viene chiamato in qualsiasi punto del sottoalbero. Questo viene utilizzato da m.mount
e m.redraw
per implementare la funzionalità di autoredraw, ma è anche esposto per casi d'uso più avanzati, come l'integrazione con alcuni framework di terze parti.
m.render
è sincrono.
Perché il DOM virtuale
Potrebbe sembrare inefficiente generare un albero di vnode a ogni ridisegno, ma in realtà, creare e confrontare strutture di dati JavaScript è sorprendentemente economico rispetto alla lettura e alla modifica del DOM.
Modificare il DOM può essere estremamente oneroso per diversi motivi. L'alternanza di letture e scritture può influire negativamente sulle prestazioni, causando la visualizzazione di diversi ridisegni del browser in rapida successione, mentre il confronto tra alberi DOM virtuali consente di raggruppare le scritture in un singolo ridisegno. Inoltre, le caratteristiche prestazionali delle varie operazioni DOM variano tra le implementazioni e possono essere difficili da apprendere e ottimizzare per tutti i browser. Ad esempio, in alcune implementazioni, la lettura di childNodes.length
ha una complessità di O(n); in altre, la lettura di parentNode
causa un ridisegno, ecc.
Al contrario, l'attraversamento di una struttura di dati JavaScript ha un profilo di prestazioni molto più prevedibile e stabile e, inoltre, un albero di vnode è implementato in modo tale da consentire ai moderni motori JavaScript di applicare ottimizzazioni aggressive come le classi nascoste per prestazioni ancora migliori.
Differenze rispetto ad altri metodi API
Il metodo m.render()
viene chiamato internamente da m.mount()
, m.route()
, m.redraw()
e m.request()
. Non viene chiamato dopo gli aggiornamenti dello stream.
A differenza di m.mount()
e m.route()
, un albero di vnode renderizzato tramite m.render()
non si ridisegna automaticamente in risposta agli eventi di visualizzazione, alle chiamate m.redraw()
o alle chiamate m.request()
. È un meccanismo di basso livello pensato per gli sviluppatori di librerie che desiderano controllare manualmente il rendering, piuttosto che fare affidamento sul sistema di ridisegno automatico integrato di Mithril.js.
Un'altra differenza è che il metodo m.render
si aspetta un vnode (o un array di vnode) come secondo parametro, mentre m.mount()
e m.route()
si aspettano componenti.
Utilizzo standalone
var render = require("mithril/render")
Il modulo m.render
ha un ambito simile a quello delle librerie di visualizzazione, come Knockout, React e Vue. Implementa un motore di differenziazione DOM virtuale con un moderno algoritmo di riduzione dello spazio di ricerca e riciclo del DOM, che si traduce in prestazioni di prim'ordine, sia in termini di caricamento iniziale della pagina che di re-rendering. Non ha dipendenze da altre parti di Mithril.js, a parte la normalizzazione esposta tramite require("mithril/render/vnode")
, e può essere utilizzato come libreria standalone.
Nonostante sia relativamente piccolo, il modulo di rendering è completamente funzionale e autosufficiente. Supporta tutto ciò che ci si potrebbe aspettare: SVG, elementi personalizzati e tutti gli attributi ed eventi validi, senza particolari limitazioni o eccezioni che fanno distinzione tra maiuscole e minuscole. Naturalmente, supporta anche completamente i componenti e i metodi del ciclo di vita.
Quando si utilizza m.render
come modulo standalone, può essere utile importare anche la funzione hyperscript
per creare i vnodes da renderizzare.