こんにちは! take です。
今回は、 JavaScript 製でクライアントサイドで使えるテンプレートエンジンの比較を行いました。 まず、機能面で比較した表がこちらです。
Mustache | Hogan | Handlebars | Underscore | EJS | jQuery.EJS | PURE | |
---|---|---|---|---|---|---|---|
delimiter | ○ | ○ | × | ○ | ○ | ○ | – |
logic-less | ○ | ○ | ○ | × | × | × | ◎ |
precompile | × | ○ | ○ | △ | ○ | × | △ |
escape | ○ | ○ | ○ | ○ | ○ | ○ | △ |
method | ○ | ○ | ◎ | ○ | ○ | ◎ | ○ |
standalone | ○ | ○ | ○ | ○ | ○ | × | × |
partials | ○ | ○ | ○ | × | △ | × | × |
項目説明:
- delimiter – テンプレートを書く際の区切り文字 ({{}} や <%%>) が変更できる。
- logic-less – テンプレート上で演算や複雑な制御構文が書けない仕様により、ロジックとテンプレートが完全に分離される。
- precompile – テンプレートを事前に実行可能な JavaScript のコードにコンパイルできる。
- escape – テンプレートエンジンで自動的に HTML エスケープができる。
- method – テンプレート上からデータとして与えられたメソッドを呼び出し、結果を挿入することができる。
- standalone – テンプレートエンジンが別途ライブラリを必要とせず単独で動く。
- partials – 部分的に別のテンプレートファイルを組み込むことができる。 (include のようなもの)
上の表で表現しきれないそれぞれのテンプレートエンジンの特徴を紹介します。
Mustache
(mustache.js v0.7.2)
logic less なことが最大の特徴で、テンプレートが複雑なロジックによって煩雑になることを防ぐことができます。
テンプレート内で if, unless, each などのキーワードを用いずに同等の機能を実現しています。
多くの言語で実装されています。
<h1>{{title}}</h1> <h2>Access Array Item</h2> {{engines.1}} <h2>Array For Each</h2> <ul> {{#engines}} <li>{{.}}</li> {{/engines}} </ul> <h2>HTML Unescaping</h2> {{{html}}} <h2>View Helper Method</h2> あなたにおすすめなテンプレートエンジンは… {{method}} です。
Hogan.js
(Hogan.js v3.0.0)
Mustache 互換のテンプレートエンジンで、 Mustache との違いはプリコンパイル可能で実行速度が速いことです。
米 Twitter 社が開発し、 Twitter で利用されています。
<h1>{{title}}</h1> <h2>Access Array Item</h2> {{engines.1}} <h2>Array For Each</h2> <ul> {{#engines}} <li>{{.}}</li> {{/engines} }</ul> <h2>HTML Unescaping</h2> {{{html}}} <h2>View Helper Method</h2> あなたにおすすめなテンプレートエンジンは… {{method}} です。
Handlebars.js
(Handlebars.js v1.0.rc.2)
Mustache によく似ていますが互換性の無いテンプレートエンジンで、 Hogan と同等以上の機能を備えながら、 if, unless, each というわかりやすいキーワードを用いることができます。
<h1>{{title}}</h1> <h2>Access Array Item</h2> {{engines.2.this}} <h2>Array For Each</h2> <ul> {{#each engines}} <li>{{.}}</li> {{/each}} </ul> <h2>HTML Unescaping</h2> {{{html}}} <h2>View Helper Method</h2> あなたにおすすめなテンプレートエンジンは… {{method}} です。
Underscore.js
(Underscore.js v1.4.3)
_.template メソッドで EJS に似た簡易的なテンプレートが利用できます。
テンプレートのコンパイルはできますが、 Hogan.js, Handlebars.js, EJS のようにコンパイル済みのスクリプトファイルを読み込んでレンダリングのようなことはできません。ページ読み込み毎にコンパイルが必要です。
<h1><%- title %></h1> <h2>Access Array Item</h2> <%- engines[3] %> <h2>Array For Each</h2> <ul> <% _.each(engines, function (engine) { %> <li><%- engine %></li> <% }) %> </ul> <h2>HTML Unescaping</h2> <%= html %> <h2>View Helper Method</h2> あなたにおすすめなテンプレートエンジンは… <%- method() %> です。
EJS
(EJS v0.8.3)
※ Jupiter EJS は開発が止まっており、 HTML エスケープに対応していないなど機能面で劣るため、ここではサーバサイドでも使える visionmedia EJS を取り上げます。
最大の特徴は、 JavaScript をテンプレートに直接埋め込んで実行することができることです。
サーバサイドでプリコンパイルする場合は partials が使えます。
<h1><%= title %></h1> <h2>Access Array Item</h2> <%= engines[4] %> <h2>Array For Each</h2> <ul> <% engines.forEach(function (engine) { %> <li><%= engine %></li> <% }) %> </ul> <h2>HTML Unescaping</h2> <%- html %> <h2>View Helper Method</h2> あなたにおすすめなテンプレートエンジンは… <%= method() %> です。
jQuery.EJS
(JavaScriptMVC v3.2.4)
Jupiter EJS を元にして開発が進められているテンプレートエンジンです。
JavaScriptMVC というフレームワークの一部として動きます。
visionmedia EJS とは互換性がありません。
<h1><%= title %></h1> <h2>Access Array Item</h2> <%= engines[5] %> <h2>Array For Each</h2> <ul> <% engines.forEach(function (engine) { %> <li><%= engine %></li> <% }) %> </ul> <h2>HTML Unescaping</h2> <%== html %> <h2>View Helper Method</h2> あなたにおすすめなテンプレートエンジンは… <%= method() %> です。
PURE
(PURE v2.68.0)
テンプレートが「HTML・データ構造・データ」の 3 層に分かれる仕様になっていて、テンプレート特有の区切り文字 (デリミタ) が一切含まれないピュアな HTML を記述することができます。
Underscore.js と同様にテンプレートのコンパイルはできますが、 Hogan.js, Handlebars.js, EJS のようにコンパイル済みのスクリプトファイルを読み込んでレンダリングはできません。
HTML
<h1 class="title"></h1> <h2>Access Array Item</h2> <p class="engine"></p> <h2>Array For Each</h2> <ul class="engines"> <li> </li> </ul> <h2>Unsupport HTML Escaping</h2> <span class="html"></span> <h2>View Helper Method</h2> <p>あなたにおすすめなテンプレートエンジンは… <span class="suggestion"></span> です。</p>
データ構造 (directive)
{ "h1.title": "title", "p.engine": "engines.6", "ul.engines li": { "engine < - engines": { ".": "engine" } }, "span.html": "html", "p > span.suggestion": "method" }
ベンチマーク
実際にブラウザで走らせて、速度にはどれほど差が出るのか比較してみました。
Benchmark test for some template engines.
[iframe height=”350px” src=”http://imaya.github.com/jsperfview/embed.html?id=agt1YS1wcm9maWxlcnINCxIEVGVzdBic29ATDA”]
↓こちらは、プリコンパイルした場合
Precompiled Templates
[iframe height=”350px” src=”http://imaya.github.com/jsperfview/embed.html?id=agt1YS1wcm9maWxlcnINCxIEVGVzdBillsoTDA”]
まとめ
JavaScript 製のテンプレートエンジンには大きく分けて 3 種類ありました。
- EJS のように JavaScript を直接埋め込んで実行できる
- Mustache のように logic-less でテンプレートからロジックが分離される
- PURE のように構造データを別途用意することで HTML を汚さない
速度の面では、 ブラウザによってはスコアが大幅に異なるものもありますが、 Hogan.js が安定して速いという結果が出ました。
一番遅いのは Handlebars.js ですが、プリコンパイルの場合は逆に最速という結果が出ています。
ここでは 7 つしか紹介していませんが、他にも多数のテンプレートエンジンがありますので、用途に応じて文法・機能・速度の点から一番最適なものを見つけてみて下さい。