render(element, vnodes)
Descrição
Renderiza um modelo no DOM.
m.render(document.body, 'hello');
// <body>hello</body>
Assinatura
m.render(element, vnodes, redraw)
Parâmetro | Tipo | Obrigatório | Descrição |
---|---|---|---|
element | Element | Sim | Um elemento DOM que será o nó pai da árvore. |
vnodes | Array<Vnode>|Vnode | Sim | Os vnodes a serem renderizados. |
redraw | () -> any | Não | Uma função de callback invocada sempre que um manipulador de evento na árvore for acionado. |
retorna | Retorna undefined . |
Como funciona
O método m.render(element, vnodes)
recebe uma árvore virtual DOM (normalmente gerada pela função m()
hyperscript), gera uma árvore DOM e a insere em element
. Se element
já possuir uma árvore DOM inserida por uma chamada anterior de m.render()
, vnodes
será comparado com a árvore vnodes
anterior e a árvore DOM existente será modificada apenas onde for necessário para refletir as mudanças. Nós DOM inalterados permanecem intocados.
Se você passar o argumento opcional redraw
, ele é invocado cada vez que um manipulador de evento em qualquer lugar da árvore é acionado. Isso é usado por m.mount
e m.redraw
para implementar a funcionalidade de autoredraw, mas também é exposto para casos de uso mais avançados, como a integração com frameworks de terceiros.
m.render
é síncrono.
Por que Virtual DOM
Pode parecer um desperdício gerar uma árvore vnode a cada redesenho, mas, surpreendentemente, criar e comparar estruturas de dados JavaScript é mais barato do que ler e modificar o DOM.
Manipular o DOM pode ser extremamente custoso por alguns motivos. Alternar entre leituras e escritas pode afetar negativamente o desempenho, causando várias repinturas do navegador em rápida sucessão, enquanto a comparação de árvores virtuais do DOM permite que as escritas sejam agrupadas em uma única repintura. Além disso, as características de desempenho de várias operações DOM variam entre as implementações e podem ser difíceis de aprender e otimizar para todos os navegadores. Por exemplo, em algumas implementações, ler childNodes.length
tem uma complexidade de O(n); em algumas, ler parentNode
causa uma repintura, etc.
Em contraste, processar uma estrutura de dados JavaScript tem um perfil de desempenho muito mais previsível e razoável e, além disso, uma árvore vnode é implementada de forma que permite que os mecanismos JavaScript modernos apliquem otimizações agressivas, como classes ocultas, para um desempenho ainda melhor.
Diferenças de outros métodos da API
O método m.render()
é chamado internamente por m.mount()
, m.route()
, m.redraw()
e m.request()
. Ele não é invocado após atualizações de stream.
Diferentemente de m.mount()
e m.route()
, uma árvore vnode renderizada por meio de m.render()
não é redesenhada automaticamente em resposta a eventos de visualização, chamadas de m.redraw()
ou chamadas de m.request()
. É um mecanismo de baixo nível adequado para desenvolvedores de bibliotecas que desejam controlar manualmente a renderização, em vez de confiar no sistema de auto-redesenho integrado do Mithril.js.
Outra diferença é que o método m.render
espera um vnode (ou um array de vnodes) como seu segundo parâmetro, enquanto m.mount()
e m.route()
esperam componentes.
Uso autônomo
var render = require("mithril/render")
O módulo m.render
possui um escopo semelhante ao de bibliotecas de visualização como Knockout, React e Vue. Ele implementa um mecanismo de diferenciação virtual DOM com um algoritmo moderno de redução de espaço de busca e reciclagem de DOM, o que resulta em desempenho de primeira classe, tanto no carregamento inicial da página quanto na re-renderização. Ele não tem dependências de outras partes do Mithril.js além da normalização exposta via require("mithril/render/vnode")
e pode ser usado como uma biblioteca independente.
Apesar de ser relativamente pequeno, o módulo de renderização é totalmente funcional e autossuficiente. Ele suporta tudo o que você pode esperar: SVG, elementos personalizados e todos os atributos e eventos válidos - sem casos extremos ou exceções estranhas que dependam de diferenciação entre maiúsculas e minúsculas. Claro, ele também suporta completamente componentes e métodos de ciclo de vida.
Ao utilizar m.render
como um módulo independente, pode ser útil importar também a função hyperscript
para criar os vnodes a serem renderizados.