自動再描画システム
- チュートリアル
- リソース
- 重要なコンセプト
- ソーシャル
- その他
Mithrilは、高速なレンダリングのために仮想DOM差分システムを実装しています。また、それに加えてアプリケーションがレンダリングをコントロールできるように、適切な粒度のさまざまなメカニズムを提供しています。
慣用的な表現をすると、Mithrilはデータレイヤーの変更をDOMに同期するために、自動再描画システムを利用しています。自動再描画システムはm.mount()
、もしくはm.route()
関数を使うと有効化されます。m.render()
呼び出しを使って画面更新を行うとこの機能は無効なままです。
自動再描画システムは単純に、特定の関数の実行が完了したら再描画関数が実行されるようになっています。
イベントハンドラ後
Mithrilは、Mithrilのビューで定義されたDOMイベントハンドラの実行後に再描画を自動で行います:
var MyComponent = {
view: function() {
return m("div", {onclick: doSomething})
}
}
function doSomething() {
// この関数の実行直後に同期的に再描画が行われる
}
m.mount(document.body, MyComponent)
特定のイベントの再描画を無効にするには、e.redraw
にfalse
を設定します。
var MyComponent = {
view: function() {
return m("div", {onclick: doSomething})
}
}
function doSomething(e) {
e.redraw = false
// このdivがクリックされても再描画は行われない
}
m.mount(document.body, MyComponent)
m.request後
Mithrilはm.request
の処理が完了した後に自動で再描画を行います:
m.request("/api/v1/users").then(function() {
// この関数の実行後に再描画が発生
})
特定のサーバーリクエスト処理後に再描画を無効にするには、background
オプションをtrueにします:
m.request("/api/v1/users", {background: true}).then(function() {
// 再描画は行われない
})
ラウトの変更後
Mithrilはm.route.set()
を呼び出したり、m.route.link
を使用したリンクをクリックした後に再描画を自動で行います:
var RoutedComponent = {
view: function() {
return [
// ラウと変更後に同期的に再描画が実行
m("a", {href: "/", oncreate: m.route.link}),
m("div", {
onclick: function() {
m.route.set("/")
}
}),
]
}
}
m.route(document.body, "/", {
"/": RoutedComponent,
})
Mithrilが再描画を行わない時
MithrilはsetTimeout
, setInterval
, requestAnimationFrame
の呼び出し、Promise、サードパーティーライブラリが提供するイベントハンドラ(例: Socket.ioのコールバック)では再描画を行いません。この場合は、手動で<a3><c4>m.redraw()</c4></a3>を呼び出す必要があります。
Mithrilはライフサイクルメソッド後にも再描画は行いません。UIの一部はoninit
ハンドラの後に再描画されますが、UIの他の部分は指定のoninit
ハンドラが起動した時にすでに再描画されているでしょう。oncreate
とonupdate
ハンドラはUIが再描画された後に呼ばれます。
ライフサイクルメソッド内で再描画を明示的に行う時はm.redraw()
を呼びます。この関数は非同期で再描画を行います。
var StableComponent = {
oncreate: function(vnode) {
vnode.state.height = vnode.dom.offsetHeight
m.redraw()
},
view: function() {
return m("div", "このコンポーネントの高さは " + vnode.state.height + "ピクセルです")
}
}
Mithrilはm.render
で描画されたvnodeツリーの再描画は行いません。m.render
を使ってレンダリングされたテンプレートに対しては、イベントの変更やm.request
の呼び出しでは再描画は行われません。そのため、Reduxのようなライブラリを使っている場合など、アーキテクチャの都合上、描画の制御をマニュアルで行う必要があれば、m.mount
の代わりにm.render
を使うべきです。
m.render
はvnodeツリーを受け取り、m.mount
はコンポーネントを受け取ります。
// m.renderのためにコンポーネントをm()でラップする
m.render(document.body, m(MyComponent))
// m.mountはコンポーネントをそのまま使用できる
m.mount(document.body, MyComponent)
Mithrilは1アニメーションフレーム(通常16ミリ秒)以内に再度再描画が行われると、自動再描画をスキップします。onresize
やonscroll
などの高頻度イベントを使って再描画を指示した場合にも、Mithrilは再描画の頻度を調整し、ラグを避けます。
License: MIT. © Leo Horie.