jQuery Templates Plugin筆記6
0 |
範本在應用前必須先經過編譯,將我們提供的範本內容(包在<script type="x-jquery-tmpl">中的HTML片段、或直接傳入的HTML字串),變成一個"輸入資料物件、輸出HTML元素的Javascript函數",而所謂"套用範本",說穿了就是"一一傳入資料物件給範本函數,取得HTML元素"的過程。
將HTML範本內容編譯成範本函數的過程,涉及不少Regular Expression置換處理,RegExp固然威力強大,但運算起來也頗耗CPU,因此jQuery Templates內建了Cache機制,只在第一次套用時產生範本函數,之後會以jQuery.data()將範本函數保存在範本的容器HTML元素上(例如: <script type=”x-jquery-tmpl”>的<script>元素),省去每次重新編譯的無謂浪費。
但問題來了,若我們直接提供範本HTML字串作為.tmpl()參數,因缺乏容器HTML元素,使難以使用jQuery.data()暫存範本函數,享用Cache機制,得採行替代做法: .template() 。
透過$(“HTML範本字串").template("範本函數Cache名稱")或$.template("範本函數Cache名稱", “HTML範本字串")將範本事先編譯保存,之後便能以$.tmpl(“範本函數Cache名稱”, 資料物件陣列)引用已編譯好的範本函數,省去每次重新編譯的功夫。另外,.template()不帶參數時傳回的就是範本函數,也可以當成.tmpl()的傳入參數,還有不少有趣的應用,之後再做介紹。
我寫了一小段範例程式原本想突顯預先編譯HTML範本字串的效能提升,並比較了.template()應用在<script type=”text/x-jquery-tmpl”>與HTML範本字串上的差別。由結果大致可看出<script>因原本就有Cache,差別不大;而HTML範本字串則有些許加快。不過可能因為範本還不夠複雜,引發的RegExp耗損不甚明顯,測試數字看不出明顯且可反覆驗證的穩定差別,不算是成功的效能測試,大家就當成應用.template()的示範參考好了。
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>jQuery Templates Lab 6 - HTML字串範本之預先編譯</title>
<script src="http://ajax.aspnetcdn.com/ajax/jquery/jquery-1.4.4.js"
type="text/javascript"></script>
<script src="http://ajax.microsoft.com/ajax/jquery.templates/beta1/jquery.tmpl.js"
type="text/javascript"></script>
<script type="text/x-jquery-tmpl" id="tmplItem">
<tr><td>${No}</td><td>${Name}</td><td>${Score}</td></tr>
<tr><td>${No}</td><td>${Name}</td><td>${Score}</td></tr>
<tr><td>${No}</td><td>${Name}</td><td>${Score}</td></tr>
<tr><td>${No}</td><td>${Name}</td><td>${Score}</td></tr>
<tr><td>${No}</td><td>${Name}</td><td>${Score}</td></tr>
<tr><td>${No}</td><td>${Name}</td><td>${Score}</td></tr>
<tr><td>${No}</td><td>${Name}</td><td>${Score}</td></tr>
<tr><td>${No}</td><td>${Name}</td><td>${Score}</td></tr>
<tr><td>${No}</td><td>${Name}</td><td>${Score}</td></tr>
<tr><td>${No}</td><td>${Name}</td><td>${Score}</td></tr>
</script>
<script type="text/javascript">
//REF: http://blog.darkthread.net/blogs/darkthreadtw/archive/2009/06/16/js-stopwatch.aspx
function darkStopWatch(timerName) {
this.timerName = timerName;
this.timerSt = new Date();
this.resultQueue = [];
this.tag = "Test";
}
darkStopWatch.prototype = {
start: function (tag) {
this.tag = tag;
this.timerSt = new Date();
},
stop: function () {
var ts = new Date() - this.timerSt;
this.resultQueue.push(this.tag + " -> " + ts + "ms");
},
getRecord: function (clear) {
var s = this.resultQueue.join("\n");
if (clear) this.clear();
return "StopWatch [" + this.timerName +
"]\n====================\n" + s;
},
reset: function () {
this.resultQueue = [];
}
}
</script>
<script type="text/javascript">
$(function () {
var data = [
{ No: 1, Name: "Jeffrey", Score: 59 },
{ No: 2, Name: "Darkthread", Score: 75 },
{ No: 3, Name: "Linda", Score: 96 }
];
var testTimes = 100;
var sw = new darkStopWatch("jQuery Templates plugin Test");
//故意重複10次讓Template複雜一點,以突顯效能差異
var ary = [];
ary.push("<tbody>");
for (var i = 0; i < 10; i++)
ary.push(
"<tr><td>${No}</td><td>${Name}</td><td>${Score}</td></tr>");
ary.push("</tbody>");
var tmplHtml = ary.join("\n");
sw.start("<script>內嵌範本");
for (var i = 1; i < testTimes; i++)
$("#tmplItem").tmpl(data); //.appendTo("#tb");
sw.stop();
sw.start("<script>內嵌範本(編譯版)");
$.template("compiledTmpl2", $("#tmplItem"));
for (var i = 1; i < testTimes; i++)
$.tmpl("compiledTmpl2", data); //.appendTo("#tb");
sw.stop();
sw.start("以HTML字串設定範本");
for (var i = 1; i < testTimes; i++)
$(tmplHtml).tmpl(data); //.appendTo("#tb");
sw.stop();
sw.start("以HTML字串設定範本(編譯版)");
$.template("compiledTmpl1", tmplHtml);
for (var i = 1; i < testTimes; i++)
$.tmpl("compiledTmpl1", data); //.appendTo("#tb");
sw.stop();
alert(sw.getRecord());
/* 測試結果範例
StopWatch [jQuery Templates plugin Test]
====================
<script>內嵌範本 -> 1112ms
<script>內嵌範本(編譯版) -> 1111ms
以HTML字串設定範本 -> 1484ms
以HTML字串設定範本(編譯版) -> 886ms
*/
});
</script>
</head>
<body>
<table><tbody id="tb"></tbody></table>
</body>
</html>
Comments
Be the first to post a comment