ホームページ  >  記事  >  ウェブフロントエンド  >  JavaScript テンプレート エンジン - tmpl のバグ修復とパフォーマンスの最適化分析_JavaScript スキル

JavaScript テンプレート エンジン - tmpl のバグ修復とパフォーマンスの最適化分析_JavaScript スキル

WBOY
WBOYオリジナル
2016-05-16 18:00:25963ブラウズ

オープンソースで利用できる優れた tmpl
フロントエンド テンプレートは数多くありますが、jQuery 作者の John Resig によって開発された「JavaScript マイクロ テンプレート」が最も優れており、わずか数ストロークでテンプレート エンジンのコア機能を実現します。
その紹介と使用法については、作者のブログを参照してください: http://ejohn.org/blog/javascript-micro-template/
まず彼のソース コードを見てみましょう:

コードをコピーします コードは次のとおりです。

(function(){
var queue = {};
this.tmpl = function (str, data){
var fn = !/W/.test(str) ?
キャッシュ[str] = キャッシュ[str] || ドキュメント.getElementById(str).innerHTML):
new Function("obj",
"var p=[],print=function(){p.push.apply(p,arguments);};"
"with(obj ){p.push('"
str
.replace(/[rtn]/g, " ")
.split(" .replace(/((^|%>)[^t]*)'/g, "$1r")
.replace(/t=(.*?)%> /g, "', $1,'")
.split("t").join("');")
.split("%>").join("p.push( '")
.split("r").join("\'")
"');}return p.join('');");
return data ? fn( data ) : fn;
};
});

スズメは、基本的なデータに加えて、キャッシュメカニズムとロジックのサポート。さて、JavaScript で最も省エネなカスタム関数をランキングするとしたら、1 位は $ 関数 (document.getElementById 短縮版)、2 位は tmpl になります。
もちろん、これは完璧ではありません。使用中にいくつかの問題が見つかりました。
tmpl にはハエが含まれています
1。

コードをコピーします コードは次のとおりです:tmpl('<%=name%>//<%=id% > ', {name:'sugar Pie', id: '1987'});
エラーが報告されます。正しく動作している場合は、次のように出力されるはずです: Sugar Cookie/1987
実際、解決策は非常に簡単です。エスケープ文字をエスケープする正規表現の行を追加します:


コードをコピーします コードは次のとおりです: str.replace(/\/g, "\\")
2. 正しく区別できない場合があります。最初のパラメータは ID またはテンプレートです。
ページ テンプレート ID に下線が付いている場合 (tmpl-photo-thumb など)、この名前のテンプレートは検索されず、渡された元のテンプレートが直接コンパイルされて出力されたものとみなされます。
元のテンプレートと要素 ID の最も直感的な違いは、スペースが含まれているかどうかです。そのため、正規表現を変更するだけです:
view sourceprint?1 !/s/.test(str)
3.内部にもテスト用のコードが残っており、削除できます。


コードをコピー コードは次のとおりです。print=function(){p.push.apply( p,arguments );}
tmpl の効率に関する疑問
少し前に YayaTemplate を紹介する Baidu mux によるソフト記事を読むまで、元の記事の著者は主要な人気のあるテンプレート エンジンに対して効率テストを実施していました。そして最終的に、最も人気のあるテンプレート エンジンは YayaTemplate であると結論付けました。 tmpl のテスト結果は YayaTemplate ほど良くありませんでしたが、実際のアプリケーションでは従来の文字列連結とほぼ同じであり、パフォーマンスに対する懸念を払拭することができました。非常に大規模な解析を実行する場合にのみ、両者の間に大きなパフォーマンスの差が生じます。 (超大規模? JavaScript 自体はこれには適していません。ある日、プログラマが一度に何千ものリスト データをブラウザに挿入し、それが非常に遅かった場合、疑いの余地はありません。問題はこのプログラマにあり、彼はユーザーのブラウザを大切にします。)
エンジン効率のランキングに関しては、これがテンプレート エンジンを測定するための主要な基準ではないと思いますが、現時点では、YayaTemplate のテンプレート構文も重要になります。さらにわかりにくいのは、テンプレート構文に巧妙な工夫を加えて、いくつかの正規表現を節約することです。
最初に YayaTemplate のソース コードを表示します:


コードをコピーします コードは次のとおりです:

//作者:yaya,jihu
//uloveit.com.cn/template
//YayaTemplate("xxx").render({}); var YayaTemplate = YayaTemplate || function(str){
//コア分析メソッド
var _analyze=function(text){
return text.replace(/{$(s|S)*?$} /g,function(s){
return s.replace(/("|\)/g,"\$1")
.replace("{$",'_s.push("')
.replace("$}",'");')
.replace(/{%([sS]*?)%}/g, '",$1,"')
}) .replace(/r|n/g,"");
};
//中間コード
var _temp = _analyze(document.getElementById(str)?document.getElementById(str).innerHTML: str);
//リターンジェネレータのレンダリングメソッド
return {
render : function(mapping){
var _a = [],_v = [],i;マッピング){
_a.push(i);
_v.push(mapping[i]);
}
return (new Function(_a,"var _s=[];" _temp " return _s;")).apply(null,_v).join("");
}
}
};


パフォーマンスの問題が 1 つ提起された場合「学術的問題」を解決するための高レベルの試み、なぜ tmpl は YayaTemplate より遅いのですか?
文法解析 YayaTemplate は JavaScript で HTML をラップする新しい方法を使用していますが、最終的には正規表現を使用して標準に解析する必要があります。 JavaScript 構文では、正規化の効率に大きな違いはなく、元のテンプレートが 1 回だけ解析されるようにするために、両方の側でキャッシュ メカニズムが使用されます。テンプレート エンジンは最終的にデータを変数の形式で保存します。テンプレートがそれを取得できるようにクロージャを追加します。まず、両者の変数宣言メカニズムを比較してみましょう:
YayaTemplate は、パラメーターを渡す従来の方法を使用して実装されています。データ オブジェクトを走査してオブジェクトの名前と値を分離し、オブジェクトのメンバー名を新しい関数のパラメーター名 (つまり、変数名) として使用し、関数の Appley 呼び出しメソッドを使用して、それらのパラメータを渡します。
tmpl は、JavaScript では一般的に使用されない with ステートメントを使用して実装されます。 実装は非常に簡単で、var キーワードが省略されています。
tmpl のパフォーマンスの問題は次のとおりです。 JavaScript によって提供される with ステートメントは、オブジェクトのプロパティにより迅速にアクセスするために使用することを目的としています。残念ながら、言語に with ステートメントが存在すると、変数名の字句スコープが妨げられるため、JavaScript エンジンの速度が大幅に低下します。
tmpl を最適化する
tmpl が wi​​th ステートメントを削除し、従来のパラメータ渡しを使用すると、実際のテスト後、240,000 個のデータの下で、Firefox で 5 倍、Chrome で 2.4 倍、Opera 1.84 でパフォーマンスが大幅に向上します。倍、Safari 2.1 倍、IE6 1.1 倍、IE9 1.35 倍、そして最終的に YayaTemplate と同点になりました。
テスト アドレス: http://www.planeart.cn/demo/tmpl/tmpl.html
Tmpl 最適化バージョンの最終コード:



コードをコピー コードは次のとおりです:

/**
* マイクロテンプレートエンジン tmpl 0.2
*
* 0.2 アップデート:
* 1. エスケープ文字と ID 判定のバグを修正
* 2. 非効率な with ステートメントを放棄して最高のパフォーマンスを実現実行効率が 3.5 倍向上しました
* 3. ランダムな内部変数を使用して、テンプレート変数との競合を防ぎます
*
* @author John Resig, Tang Bin
* @see http://ejohn.org/ blog/javascript-micro-template/
* @name tmpl
* @param {String} テンプレートのコンテンツ、またはテンプレートのコンテンツを含む要素 ID
* @param {Object} 追加データ
* @return { String} 解析されたテンプレート
*
* @example
* 方法 1: ページにテンプレートを埋め込む
*