2010年4月アーカイブ

はじめに

この記事では、JavaScript 用のテンプレートエンジン Jarty を紹介します。

Jarty (じゃーてぃー) とは、PHP の有名なテンプレートエンジンである Smarty を JavaScript に移植したものです。ただし、完全に再現しているわけではなく、いくつかの機能は制限されています。

Jarty には以下のような機能があります。書式の多くは Smarty 互換です。

  • 変数の置換 {$foo} => "abc"
  • {if} {else} {/if} などの条件分岐
  • {foreach} {/foreach} などのループ
  • {$foo|upper|escape} などのフィルタ (パイプ)
  • etc.

ソースコードは The MIT License として公開しています。

GitHub 上のリポジトリ: http://github.com/kotas/jarty

また、弊社ウェブサービスであるニコニコ動画の一部ページでも利用しています。

背景

Smarty は主にサーバーサイドで使うものですが、Jarty はクライアントサイドで利用する事を想定しています。

ウェブサービスによって JSONP 形式で公開されている API を JavaScript から利用する場合、結果を JavaScript 内のオブジェクトとして受け取る事が出来ますが、その表示をどうするか困る場合があります。

例えば、以下のような方法で表示できます。

  1. HTML 文を組み立て、innerHTML にまるごと入れる
  2. class や id などに基づいて動的に DOM を書き換える

1 の方法では、JavaScript を書く人と HTML を書く人が違う場合に困ります。また、JavaScript のコード中に HTML が混じるため、読みづらくなる欠点があります。

2 の方法では、JavaScript 中に HTML が混じる事はありませんが、最終的な DOM がどうなるのか JavaScript コードを追わないとわからない、DOM 構造を変えたら JavaScript 側の修正も必要、などの欠点があります。

Jarty を使うと、テンプレートの記述を分離でき、かつ比較的自由度の高いデザインが可能になります。また、テンプレートは HTML ベースなので、JavaScript が分からない人でも読み書きできます。

使い方

jarty.js をページ上に読み込みます。

<script src="jarty.js" type="text/javascript" charset="utf-8"></script>

簡単な使い方は以下のようになります。

var template = "Hello, {$foo}!";
var dictionary = { foo: "world" };

Jarty.eval(template, dictionary);
    // => "Hello, world!"

もっと複雑な例は、以下のページから確認できます。

内部の処理について

Jarty は、受け取ったテンプレート文字列を内部的に JavaScript の関数オブジェクト (Function) にコンパイルしています。

例として、以下のようなテンプレートは

Hello, {$foo}!

以下のような JavaScript 関数にコンパイルされます。(実際にはもうちょっと複雑です)

function (d) {
    var s = "";
    s += "Hello, ";
    s += d["foo"];
    s += "!";
    return s;
}

Jarty.compile() 関数で、テンプレートをコンパイルして関数オブジェクトを取得できます。

var compiled = Jarty.compile(template);
compiled({ foo: "world" });
    // => "Hello, world!"
compiled({ foo: "Jarty" });
    // => "Hello, Jarty!"

同じテンプレートを何度も利用する場合は、コンパイルされた関数オブジェクトを 使い回す事で速度を得る事ができます。

ベンチマーク

ベンチマーク結果は JavaScript エンジンの性能によって大きく左右されるため、Windows マシン上 (Intel Core2 1.86GHz + 2GB RAM) でいくつかのブラウザで確認してみました。

ベンチマークに利用したページ

いくつかの変数置換、{foreach}、{if} を含むテンプレート文字列を 1000 回評価すると、以下のようになりました。

Each-time Compile
  Mozilla Firefox
    1224 ms (817 回/秒)
  Internet Explorer 6
    3828 ms (261 回/秒)
  Internet Explorer 7
    3984 ms (251 回/秒)
  Internet Explorer 8
    2500 ms (400 回/秒)
  Google Chrome
    381 ms  (2625 回/秒)
  Opera
    1343 ms (745 回/秒)
  Safari
    703 ms  (1422 回/秒)

Google Chrome の早さが目立ちますね。一番遅い IE6〜7 でも 250 回/秒ほど回りました。

また、コンパイル済みの関数オブジェクトを使い回して 1000 回評価すると、以下のようになります。

Precompile
  Mozilla Firefox
    65 ms  (15385 回/秒)
  Internet Explorer 6
    265 ms (3774 回/秒)
  Internet Explorer 7
    281 ms (3559 回/秒)
  Internet Explorer 8
    156 ms (6410 回/秒)
  Google Chrome
    7 ms   (142857 回/秒)
  Opera
    31 ms  (32258 回/秒)
  Safari
    14 ms  (71429 回/秒)

毎回コンパイルするのに比べて、コンパイル済み関数オブジェクトを使い回すと、圧倒的に速度が勝っているのを確認できます。

おわりに

JavaScript 用のテンプレートエンジン Jarty を紹介しました。

なお、Jarty のソースコード、及びこの記事中に含まれるコードは全て The MIT License です。

Jarty のソースコードは GitHub 上のリポジトリ を参照してください。

Enjoy!

このアーカイブについて

このページには、2010年4月に書かれたブログ記事が新しい順に公開されています。

前のアーカイブは2010年3月です。

次のアーカイブは2010年6月です。

最近のコンテンツはインデックスページで見られます。過去に書かれたものはアーカイブのページで見られます。