<!DOCTYPE HTML>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>template test</title>
<script src="js/jquery-1.7.2.min.js"></script>
<script src="js/highcharts.js"></script>


<script src="../dist/template-native.js"></script>
<script src="js/tmpl.js"></script>
<script src="js/doT.js"></script>
<script src="js/juicer.js"></script>
<script src="js/kissy.js"></script>
<script src="js/template.js"></script>
<script src="js/mustache.js"></script>
<script src="js/handlebars.js"></script>
<script src="js/baiduTemplate.js"></script>
<script src="js/jquery.tmpl.js"></script>
<script src="js/easytemplate.js"></script>
<script src="js/underscore.js"></script>
<script src="js/etpl.js"></script>


<script>
// 数据量
var length = 100;
// 渲染次数
var number = 10000;

var data = {
    list: []
};

for (var i = 0; i < length; i ++) {
    data.list.push({
        index: i,
        user: '<strong style="color:red">糖饼</strong>',
        site: 'http://www.planeart.cn',
        weibo: 'http://weibo.com/planeart',
        QQweibo: 'http://t.qq.com/tangbin'  
    }); 
};


// 待测试的引擎列表
var testList = [

    {
        name: 'artTemplate',
        tester: function () {
            //template.config('escape', false);
            var source = document.getElementById('template').innerHTML;
            var fn = template.compile(source);
            for (var i = 0; i < number; i ++) {
                fn(data);
            }
        }
    },
    
    {
        name: 'juicer',
        tester: function () {
            var config = {cache:true};

            var source = document.getElementById('juicer').innerHTML;
            for (var i = 0; i < number; i ++) {
                juicer.to_html(source, data, config);
            }
        }
    },
    
    {
        name: 'doT',
        tester: function () {
            var source = document.getElementById('doT').innerHTML;
            var doTtmpl = doT.template(source);
            for (var i = 0; i < number; i ++) {
                doTtmpl(data);
            }
        }
    },
    
    {
        name: 'Handlebars',
        tester: function () {
            var source = document.getElementById('Handlebars').innerHTML;
            var fn = Handlebars.compile(source);
            for (var i = 0; i < number; i ++) {
                fn(data);
            }
        }
    },

    {
        name: 'etpl',
        tester: function () {
            // dont escape html
            etpl.config({
                defaultFilter: ''
            });
            var source = document.getElementById('etpl').innerHTML;
            var fn = etpl.compile(source);
            for (var i = 0; i < number; i ++) {
                fn(data);
            }
        }
    },
    
    {
        name: 'tmpl',
        tester: function () {
            var source = document.getElementById('tmpl').innerHTML;
            var fn = tmpl(source);
            for (var i = 0; i < number; i ++) {
                fn(data);
            }
        }
    },
    
    {
        name: 'easyTemplate',
        tester: function () {
            var source = document.getElementById('easyTemplate').innerHTML;
            var fn = easyTemplate(source);
            for (var i = 0; i < number; i ++) {
                // easyTemplate 渲染方法被重写到 toString(), 需要取值操作才会运行
                fn(data) + '';
            }
        }
    },

    {
        name: 'underscoreTemplate',
        tester: function () {
            var source = document.getElementById('underscoreTemplate').innerHTML;
            var fn = _.template(source);
            for (var i = 0; i < number; i ++) {
                fn(data);
            }
        }
    },
    
    {
        name: 'baiduTemplate',
        tester: function () {
            var bt=baidu.template;
            bt.ESCAPE = false;
            for (var i = 0; i < number; i ++) {
                bt('baidu-template', data);
            }
        }
    },
    
     // jqueryTmpl 太慢，可能导致浏览器停止响应
    /*{
        name: 'jqueryTmpl',
        tester: function () {
            var source = document.getElementById("jqueryTmpl").innerHTML;
            for (var i = 0; i < number; i ++) {
                $.tmpl(source, data);
            }
        }
    },*/
    
    {
        name: 'Mustache',
        tester: function () {
            var source = document.getElementById('Mustache').innerHTML;
            for (var i = 0; i < number; i ++) {
                Mustache.to_html(source, data);
            }
        }
    }
    
];

KISSY.use('template',function(S,T) {
    testList.push({
        name: 'kissyTemplate',
        tester: function () {
            var source= document.getElementById('kissy').innerHTML;

            for (var i = 0; i < number; i ++) {
                T(source).render(data);
            }
        }
    });
});


var startTest = function () {

    var Timer = function (){
        this.startTime = + new Date;
    };

    Timer.prototype.stop = function(){
        return + new Date - this.startTime;
    };
    
    var colors = Highcharts.getOptions().colors;
    var categories = [];

    for (var i = 0; i < testList.length; i ++) {
        categories.push(testList[i].name);
    }

    var chart = new Highcharts.Chart({
        chart: {
            renderTo: 'container',
            height: categories.length * 40,
            type: 'bar'
        },

        title: {
            text: 'JavaScript 模板引擎负荷测试'
        },

        subtitle: {
            text: length + ' 条数据 × ' + number + ' 次渲染'
        },
                
        xAxis: {
            categories: categories,
            labels: {
                align: 'right',
                style: {
                    fontSize: '12px',
                    fontFamily: 'Verdana, sans-serif'
                }
            }
        },

        yAxis: {
            min: 0,
            title: {
                text: '耗时(毫秒)'
            }
        },

        legend: {
            enabled: false
        },

        tooltip: {
            formatter: function() {
                return '<b>'+ this.x +'</b><br/>'+
                    this.y + '毫秒';
            }

        },

        credits: {
            enabled: false
        },
        plotOptions: {
            bar: {
                dataLabels: {
                    enabled: true,
                    formatter: function () {
                        return this.y + 'ms';
                    }
                }
            }
        },
        series: [{
            data : []
        }]

    });
    
    var log = function (message) {
        document.getElementById('log').innerHTML = message;
    };
    
    var tester = function (target) {
    
        
        var time = new Timer;
        target.tester();
        var endTime = time.stop();
        
        chart.series[0].addPoint({
            color: colors.shift(),
            y: endTime
        });
        
        
        if (!testList.length) {
            log('测试已完成，请不要迷恋速度');
            return;
        }

        target = testList.shift();
        
        log('正在测试: ' + target.name + '..');
        
        setTimeout(function () {
            tester(target);
        }, 500);
        
    };
    
    var target = testList.shift();
    log('正在测试: ' + target.name + '..');
    tester(target);

};
</script>





<!-- artTemplate 的模板 -->
<script id="template" type="text/tmpl">
<ul>
    <% for (i = 0, l = list.length; i < l; i ++) { %>
        <li>用户: <%=#list[i].user%>/ 网站：<%=#list[i].site%></li>
    <% } %>
</ul>
</script>

<!-- baidu-template 的模板 -->
<script id="baidu-template" type="text/tmpl">
<ul>
    <% for (var val, i = 0, l = list.length; i < l; i ++) { %>
        <% val = list[i]; %>
        <li>用户: <%:=val.user%>/ 网站：<%:=val.site%></li>
    <% } %>
</ul>
</script>

<!-- easyTemplate 的模板 -->
<script id="easyTemplate" type="text/tmpl">
<ul>
    <#list data.list as item>
        <li>用户: ${item.user}/ 网站：${item.site}</li>
    </#list>
</ul>
</script>

<!-- tmpl 的模板 -->
<script id="tmpl" type="text/tmpl">
<ul>
    <% for (var val, i = 0, l = list.length; i < l; i ++) { %>
        <% val = list[i]; %>
        <li>用户: <%=val.user%>/ 网站：<%=val.site%></li>
    <% } %>
</ul>
</script>

<!-- jqueryTmpl 的模板 -->
<script id="jqueryTmpl" type="text/tmpl">
<ul>
    {{each list}}
        <li>用户: ${$value.user}/ 网站：${$value.site}</li>
    {{/each}}
</ul>
</script>

<!--juicer 的模板 -->
<script id="juicer" type="text/tmpl">
<ul>
    {@each list as val}
        <li>用户: $${val.user}/ 网站：$${val.site}</li>
    {@/each}
</ul>
</script>

<!--etpl 的模板 -->
<script id="etpl" type="text/tmpl">
<ul>
    <!--for: ${list} as ${val} -->
        <li>用户: ${val.user}/ 网站：${val.site}</li>
    <!--/for-->
</ul>
</script>

<!-- doT 的模板 -->
<script id="doT" type="text/tmpl">
<ul>
    {{ for (var val, i = 0, l = it.list.length; i < l; i ++) { }}
        {{ val = it.list; }}
        <li>用户: {{=val[i].user}}/ 网站：{{=val[i].site}}</li>
    {{ } }}
</ul>
</script>

<!--Mustache 的模板 -->
<script id="Mustache" type="text/tmpl">
<ul>
    {{#list}}
        <li>用户: {{{user}}}/ 网站：{{{site}}}</li>
    {{/list}}
</ul>
</script>

<!--Handlebars  的模板 -->
<script id="Handlebars" type="text/tmpl">
<ul>
    {{#list}}
        <li>用户: {{{user}}}/ 网站：{{{site}}}</li>
    {{/list}}
</ul>
</script>

<!--kissy 的模板 -->
<script id="kissy" type="text/tmpl">
<ul>
    {{#each list as val}}
        <li>用户: {{val.user}}/ 网站：{{val.site}}</li>
    {{/each}}
</ul>
</script>


<!-- ejs 的模板 -->
<script id="ejs" type="text/tmpl">
<ul>
  <& for (var val, i = 0, l = @list.length; i < l; i ++) { &>
        <& val = @list[i]; &>
        <li>用户: <&= val.user &>； 网站：<&= val.site &></li> 
  <& } &>
</ul>
</script>

<!-- underscore 的模板 -->
<script id="underscoreTemplate" type="text/tmpl">
<ul>
    <% for (var i = 0, l = list.length; i < l; i ++) { %>
        <li>用户: <%=list[i].user%>/ 网站：<%=list[i].site%></li>
    <% } %>
</ul>
</script>
</head>

<body>
<h1>引擎渲染速度测试</h1>
<p><strong><script>document.write(length)</script></strong> 条数据 × <strong><script>document.write(number)</script></strong> 次渲染测试 [escape:false, cache:true]</p>
<p><em>建议在拥有 v8 javascript 引擎的 chrome 浏览器上进行测试，避免浏览器停止响应</em></p>
<p><button id="button-test" onclick="this.disabled=true;startTest()" style="padding: 5px;">开始测试&raquo;</button> <span id="log" style="font-size:12px"><script>for (var i = 0; i < testList.length; i ++) {document.write(testList[i].name + '; ')}</script></span></p>
<div id="container" style="min-width: 400px; margin: 0 auto"></div>
</body>
</html>