Polymerの新しい描画エンジンが 次世代HTMLテンプレートライブラリ と謳う lit-html になっているので勉強してみました。
lit-htmlとは
- サイズが小さく高速 → JSベンチマーク
- VirtualDOMを使わない
- 2-way(双方向)bindingじゃない
- HTML in JSで文字列テンプレートの中にJSを埋め込む
-
html
タグリテラル関数でテンプレートをつくり、render()
で描画。directive()
でヘルパー関数をつくる - WebコンポーネントにするにはLitElementとして使うと便利
まあ、Chromeの開発チーム(ブラウザベンダ)がつくっているので、「DOMは遅いからVDOM」とか「JSの中にHTMLっぽいもの入れようぜ(JSX)」じゃなくてよいです。
ただ、2-way bindingに慣れていた身からするとReactぽい(?)描画や状態管理を勉強しなければならなさそうです、、、
どう使うか
<!doctype html>
<script type="module">
import {html, render} from 'https://unpkg.com/lit-html?module'
render(html`Hello World !`, document.body)
</script>
type=module
、、、? ES ModuleということはIE11で動かないのでしょうが、いくつか公開されているlit-htmlを使っているサンプルアプリがIE11で動いているので大丈夫なのでしょう。
html
タグテンプレートリテラル
html`Hello World !`
ES2015/ES6で追加されたTagged Template literalが使用されていて、
const hello = name => html`Hello ${name}`
render(hello('World'), document.body)
こんな感じで値を入れて描画することができます。
const fizzBuzz = count => html`<ul>${[...Array(count)].map((_, i) => html`<li>${((i+1) % 3 == 0 ? 'Fizz' : '') + ((i+1) % 5 == 0 ? 'Buzz' : '') || (i+1)}</li>`)}</ul>`
render(fizzBuzz(20), document.body)
ループや条件式も入れることができます。
render
レンダラー
render(html`hoge`, document.querySelector("#container"))
html
で生成されたテンプレートはrender()
で指定されたDOM以下に展開されますが、これだけならこちらの記事のように自分で拡張すれば済みそうです。
どうも作者の記事によると、内部で生成されたTemplateResult
オブジェクトにParts
オブジェクトで目印をつくっておいてDOMをキャッシュしながら部分的に置換していくのが、Appleから出てきたTemplate Instantiationの仕様提案と親和性があってよい! らしい。。。
directive
プラグイン的な
基本html
とrender()
しかないのでdirective()
という関数で拡張させます。以下の例は標準で用意されているwhen
とrepeat
です。
JSの評価式やループとの違いは上述のPart
オブジェクトによって遅延評価されたり、DOMにキャッシュされるのが利点のようです。
import {html, render} from 'https://unpkg.com/lit-html?module'
import {when} from 'https://unpkg.com/lit-html/directives/when?module'
import {repeat} from 'https://unpkg.com/lit-html/directives/repeat?module'
const fizzBuzz = count => html`<ul>
${repeat(
[...Array(count)].map((_, i) => i + 1),
i=>i,
i => html`<li>${
when(i % 3 == 0 && i % 5 == 0, ()=>'FizzBuzz', ()=>when(i % 3 == 0, ()=>'Fizz', ()=>when(i % 5 == 0, ()=>'Buzz', ()=>i))
)}</li>`
)}</ul>`
render(fizzBuzz(20), document.body)
他
HTMLタグに対する属性(attribute
)やスタイル、イベントリスナーへの登録などは書き方が特殊みたいですが、次回 LitElement を勉強する時に見てみたいと思ってます。
(続き LitElement+TypeScriptでTodoリスト)
参考URL
- 本家 - GitHub
- lit-html-examples いろいろなサンプル
- awsome-lit-html lit-html関連のリンク集
- lit-html Clock SVGを書き換えていく例