test-speed.html 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446
  1. <!DOCTYPE HTML>
  2. <html>
  3. <head>
  4. <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
  5. <title>template test</title>
  6. <script src="js/jquery-1.7.2.min.js"></script>
  7. <script src="js/highcharts.js"></script>
  8. <script src="../dist/template-native.js"></script>
  9. <script src="js/tmpl.js"></script>
  10. <script src="js/doT.js"></script>
  11. <script src="js/juicer.js"></script>
  12. <script src="js/kissy.js"></script>
  13. <script src="js/template.js"></script>
  14. <script src="js/mustache.js"></script>
  15. <script src="js/handlebars.js"></script>
  16. <script src="js/baiduTemplate.js"></script>
  17. <script src="js/jquery.tmpl.js"></script>
  18. <script src="js/easytemplate.js"></script>
  19. <script src="js/underscore.js"></script>
  20. <script src="js/etpl.js"></script>
  21. <script>
  22. // 数据量
  23. var length = 100;
  24. // 渲染次数
  25. var number = 10000;
  26. var data = {
  27. list: []
  28. };
  29. for (var i = 0; i < length; i ++) {
  30. data.list.push({
  31. index: i,
  32. user: '<strong style="color:red">糖饼</strong>',
  33. site: 'http://www.planeart.cn',
  34. weibo: 'http://weibo.com/planeart',
  35. QQweibo: 'http://t.qq.com/tangbin'
  36. });
  37. };
  38. // 待测试的引擎列表
  39. var testList = [
  40. {
  41. name: 'artTemplate',
  42. tester: function () {
  43. //template.config('escape', false);
  44. var source = document.getElementById('template').innerHTML;
  45. var fn = template.compile(source);
  46. for (var i = 0; i < number; i ++) {
  47. fn(data);
  48. }
  49. }
  50. },
  51. {
  52. name: 'juicer',
  53. tester: function () {
  54. var config = {cache:true};
  55. var source = document.getElementById('juicer').innerHTML;
  56. for (var i = 0; i < number; i ++) {
  57. juicer.to_html(source, data, config);
  58. }
  59. }
  60. },
  61. {
  62. name: 'doT',
  63. tester: function () {
  64. var source = document.getElementById('doT').innerHTML;
  65. var doTtmpl = doT.template(source);
  66. for (var i = 0; i < number; i ++) {
  67. doTtmpl(data);
  68. }
  69. }
  70. },
  71. {
  72. name: 'Handlebars',
  73. tester: function () {
  74. var source = document.getElementById('Handlebars').innerHTML;
  75. var fn = Handlebars.compile(source);
  76. for (var i = 0; i < number; i ++) {
  77. fn(data);
  78. }
  79. }
  80. },
  81. {
  82. name: 'etpl',
  83. tester: function () {
  84. // dont escape html
  85. etpl.config({
  86. defaultFilter: ''
  87. });
  88. var source = document.getElementById('etpl').innerHTML;
  89. var fn = etpl.compile(source);
  90. for (var i = 0; i < number; i ++) {
  91. fn(data);
  92. }
  93. }
  94. },
  95. {
  96. name: 'tmpl',
  97. tester: function () {
  98. var source = document.getElementById('tmpl').innerHTML;
  99. var fn = tmpl(source);
  100. for (var i = 0; i < number; i ++) {
  101. fn(data);
  102. }
  103. }
  104. },
  105. {
  106. name: 'easyTemplate',
  107. tester: function () {
  108. var source = document.getElementById('easyTemplate').innerHTML;
  109. var fn = easyTemplate(source);
  110. for (var i = 0; i < number; i ++) {
  111. // easyTemplate 渲染方法被重写到 toString(), 需要取值操作才会运行
  112. fn(data) + '';
  113. }
  114. }
  115. },
  116. {
  117. name: 'underscoreTemplate',
  118. tester: function () {
  119. var source = document.getElementById('underscoreTemplate').innerHTML;
  120. var fn = _.template(source);
  121. for (var i = 0; i < number; i ++) {
  122. fn(data);
  123. }
  124. }
  125. },
  126. {
  127. name: 'baiduTemplate',
  128. tester: function () {
  129. var bt=baidu.template;
  130. bt.ESCAPE = false;
  131. for (var i = 0; i < number; i ++) {
  132. bt('baidu-template', data);
  133. }
  134. }
  135. },
  136. // jqueryTmpl 太慢,可能导致浏览器停止响应
  137. /*{
  138. name: 'jqueryTmpl',
  139. tester: function () {
  140. var source = document.getElementById("jqueryTmpl").innerHTML;
  141. for (var i = 0; i < number; i ++) {
  142. $.tmpl(source, data);
  143. }
  144. }
  145. },*/
  146. {
  147. name: 'Mustache',
  148. tester: function () {
  149. var source = document.getElementById('Mustache').innerHTML;
  150. for (var i = 0; i < number; i ++) {
  151. Mustache.to_html(source, data);
  152. }
  153. }
  154. }
  155. ];
  156. KISSY.use('template',function(S,T) {
  157. testList.push({
  158. name: 'kissyTemplate',
  159. tester: function () {
  160. var source= document.getElementById('kissy').innerHTML;
  161. for (var i = 0; i < number; i ++) {
  162. T(source).render(data);
  163. }
  164. }
  165. });
  166. });
  167. var startTest = function () {
  168. var Timer = function (){
  169. this.startTime = + new Date;
  170. };
  171. Timer.prototype.stop = function(){
  172. return + new Date - this.startTime;
  173. };
  174. var colors = Highcharts.getOptions().colors;
  175. var categories = [];
  176. for (var i = 0; i < testList.length; i ++) {
  177. categories.push(testList[i].name);
  178. }
  179. var chart = new Highcharts.Chart({
  180. chart: {
  181. renderTo: 'container',
  182. height: categories.length * 40,
  183. type: 'bar'
  184. },
  185. title: {
  186. text: 'JavaScript 模板引擎负荷测试'
  187. },
  188. subtitle: {
  189. text: length + ' 条数据 × ' + number + ' 次渲染'
  190. },
  191. xAxis: {
  192. categories: categories,
  193. labels: {
  194. align: 'right',
  195. style: {
  196. fontSize: '12px',
  197. fontFamily: 'Verdana, sans-serif'
  198. }
  199. }
  200. },
  201. yAxis: {
  202. min: 0,
  203. title: {
  204. text: '耗时(毫秒)'
  205. }
  206. },
  207. legend: {
  208. enabled: false
  209. },
  210. tooltip: {
  211. formatter: function() {
  212. return '<b>'+ this.x +'</b><br/>'+
  213. this.y + '毫秒';
  214. }
  215. },
  216. credits: {
  217. enabled: false
  218. },
  219. plotOptions: {
  220. bar: {
  221. dataLabels: {
  222. enabled: true,
  223. formatter: function () {
  224. return this.y + 'ms';
  225. }
  226. }
  227. }
  228. },
  229. series: [{
  230. data : []
  231. }]
  232. });
  233. var log = function (message) {
  234. document.getElementById('log').innerHTML = message;
  235. };
  236. var tester = function (target) {
  237. var time = new Timer;
  238. target.tester();
  239. var endTime = time.stop();
  240. chart.series[0].addPoint({
  241. color: colors.shift(),
  242. y: endTime
  243. });
  244. if (!testList.length) {
  245. log('测试已完成,请不要迷恋速度');
  246. return;
  247. }
  248. target = testList.shift();
  249. log('正在测试: ' + target.name + '..');
  250. setTimeout(function () {
  251. tester(target);
  252. }, 500);
  253. };
  254. var target = testList.shift();
  255. log('正在测试: ' + target.name + '..');
  256. tester(target);
  257. };
  258. </script>
  259. <!-- artTemplate 的模板 -->
  260. <script id="template" type="text/tmpl">
  261. <ul>
  262. <% for (i = 0, l = list.length; i < l; i ++) { %>
  263. <li>用户: <%=#list[i].user%>/ 网站:<%=#list[i].site%></li>
  264. <% } %>
  265. </ul>
  266. </script>
  267. <!-- baidu-template 的模板 -->
  268. <script id="baidu-template" type="text/tmpl">
  269. <ul>
  270. <% for (var val, i = 0, l = list.length; i < l; i ++) { %>
  271. <% val = list[i]; %>
  272. <li>用户: <%:=val.user%>/ 网站:<%:=val.site%></li>
  273. <% } %>
  274. </ul>
  275. </script>
  276. <!-- easyTemplate 的模板 -->
  277. <script id="easyTemplate" type="text/tmpl">
  278. <ul>
  279. <#list data.list as item>
  280. <li>用户: ${item.user}/ 网站:${item.site}</li>
  281. </#list>
  282. </ul>
  283. </script>
  284. <!-- tmpl 的模板 -->
  285. <script id="tmpl" type="text/tmpl">
  286. <ul>
  287. <% for (var val, i = 0, l = list.length; i < l; i ++) { %>
  288. <% val = list[i]; %>
  289. <li>用户: <%=val.user%>/ 网站:<%=val.site%></li>
  290. <% } %>
  291. </ul>
  292. </script>
  293. <!-- jqueryTmpl 的模板 -->
  294. <script id="jqueryTmpl" type="text/tmpl">
  295. <ul>
  296. {{each list}}
  297. <li>用户: ${$value.user}/ 网站:${$value.site}</li>
  298. {{/each}}
  299. </ul>
  300. </script>
  301. <!--juicer 的模板 -->
  302. <script id="juicer" type="text/tmpl">
  303. <ul>
  304. {@each list as val}
  305. <li>用户: $${val.user}/ 网站:$${val.site}</li>
  306. {@/each}
  307. </ul>
  308. </script>
  309. <!--etpl 的模板 -->
  310. <script id="etpl" type="text/tmpl">
  311. <ul>
  312. <!--for: ${list} as ${val} -->
  313. <li>用户: ${val.user}/ 网站:${val.site}</li>
  314. <!--/for-->
  315. </ul>
  316. </script>
  317. <!-- doT 的模板 -->
  318. <script id="doT" type="text/tmpl">
  319. <ul>
  320. {{ for (var val, i = 0, l = it.list.length; i < l; i ++) { }}
  321. {{ val = it.list; }}
  322. <li>用户: {{=val[i].user}}/ 网站:{{=val[i].site}}</li>
  323. {{ } }}
  324. </ul>
  325. </script>
  326. <!--Mustache 的模板 -->
  327. <script id="Mustache" type="text/tmpl">
  328. <ul>
  329. {{#list}}
  330. <li>用户: {{{user}}}/ 网站:{{{site}}}</li>
  331. {{/list}}
  332. </ul>
  333. </script>
  334. <!--Handlebars 的模板 -->
  335. <script id="Handlebars" type="text/tmpl">
  336. <ul>
  337. {{#list}}
  338. <li>用户: {{{user}}}/ 网站:{{{site}}}</li>
  339. {{/list}}
  340. </ul>
  341. </script>
  342. <!--kissy 的模板 -->
  343. <script id="kissy" type="text/tmpl">
  344. <ul>
  345. {{#each list as val}}
  346. <li>用户: {{val.user}}/ 网站:{{val.site}}</li>
  347. {{/each}}
  348. </ul>
  349. </script>
  350. <!-- ejs 的模板 -->
  351. <script id="ejs" type="text/tmpl">
  352. <ul>
  353. <& for (var val, i = 0, l = @list.length; i < l; i ++) { &>
  354. <& val = @list[i]; &>
  355. <li>用户: <&= val.user &>; 网站:<&= val.site &></li>
  356. <& } &>
  357. </ul>
  358. </script>
  359. <!-- underscore 的模板 -->
  360. <script id="underscoreTemplate" type="text/tmpl">
  361. <ul>
  362. <% for (var i = 0, l = list.length; i < l; i ++) { %>
  363. <li>用户: <%=list[i].user%>/ 网站:<%=list[i].site%></li>
  364. <% } %>
  365. </ul>
  366. </script>
  367. </head>
  368. <body>
  369. <h1>引擎渲染速度测试</h1>
  370. <p><strong><script>document.write(length)</script></strong> 条数据 × <strong><script>document.write(number)</script></strong> 次渲染测试 [escape:false, cache:true]</p>
  371. <p><em>建议在拥有 v8 javascript 引擎的 chrome 浏览器上进行测试,避免浏览器停止响应</em></p>
  372. <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>
  373. <div id="container" style="min-width: 400px; margin: 0 auto"></div>
  374. </body>
  375. </html>