render(element, vnodes)
- コア
- オプショナル
- ツール
説明
テンプレートをDOMにレンダリングします
m.render(document.body, "hello")
// <body>hello</body>
シグニチャ
m.render(element, vnodes)
引数 | 型 | 必須 | 説明 |
---|---|---|---|
element |
Element |
Yes | サブツリーの親ノードとなるDOM要素 |
vnodes |
Array<Vnode>|Vnode |
Yes | レンダリング対象のvnode |
返り値 | undefined を返す |
どのように動作するのか
m.render(element, vnodes)
メソッドは仮想DOMツリー(通常はm()
hyperscript 関数で作成)を受け取り、DOMを生成してelement
にマウントします。以前にm.render()
を同一のelement
に対して呼び出していて、すでにDOMツリーがマウントされていたら、vnodes
と以前のvnodes
の差分を計算し、変更を反映します。変更がないDOMは触れられません。
m.render
は同期実行されます。
なぜ仮想DOMか
すべての再描画でvnodeツリーを生成するのは無駄に思えるかもしれませんが、JavaScriptのデータ構造の作成と比較は、DOMの読み取りと変更に比べてかなりコストに差があり、メリットがあります。
DOMを触るのはいくつかの理由により高コストになります。読取りと書込みを交互に行うと、ブラウザに寄っては再表示が連続して発生しパフォーマンスに悪影響を及ぼします。一方、仮想DOMツリーでは再描画1回のコストで済みます。また、DOM操作のパフォーマンス特性はブラウザ実装によって異なるため、すべてのブラウザで最適化するのが簡単ではありません。例えば、childNodes.length
にアクセスするだけO(n)のコストがかかり、parentNode
にアクセスすると再描画が行われるブラウザもあります。
JavaScriptのデータ構造のトラバースでは、割り込みが入ることもなく予測可能で安定したパフォーマンス特性を発揮します。これに加えて、モダンなJavaScriptエンジンではhidden classのような積極的な最適化を行います。
他のAPIメソッドとの違い
m.render()
メソッドはm.mount()
, m.route()
, m.redraw()
, m.request()
から内部的に呼ばれる関数です。ストリームの更新後には呼ばれません。
m.mount()
、m.route()
と異なり、m.render()
を使ったvnodeツリーのレンダリングは、ビューイベント、m.redraw()
呼び出し、m.request()
呼び出しに対して自動的に行われることはありません。このメソッドは、Mithrilに組み込みの自動再描画システムではなく、手動でレンダリングを制御したいと思えるライブラリ作者にマッチするような、低レベルのメカニズムです。
m.render
がvnode(やその配列)を第二引数として取り、m.mount()
とm.route()
がコンポーネントを引数に取る点も異なります。
単独での使用方法
var render = require("mithril/render")
m.render
モジュールはKnockout、React, VueといったViewライブラリと似たスコープを持ちます。これは、約500行のコード(gzipすると3kb未満)で、初期ページの読み込みと再描画の両方において、最新の検索スペース削減アルゴリズムとDOMリサイクルを備えたバーチャルDOM差分検知エンジンを実装されています。このコードは他のMthrilのコードには依存しておらず、単独のライブラリとして使用できます。
コードサイズが極めて小さいにもかかわらず、完全な機能を備えており、外部依存がなく独立しています。この関数はSVG、カスタム要素、およびすべての有効な属性とイベントをサポートしています。大文字と小文字を区別することはありません。例外もありません。 もちろん、この関数は コンポーネントとライフサイクルメソッドも完全にサポートしています。
License: MIT. © Leo Horie.