aralejs / widget

The Base Class of Widget
aralejs.org/widget/
53 stars 42 forks source link

渲染模板的性能问题 #28

Closed shaoshuai0102 closed 11 years ago

shaoshuai0102 commented 11 years ago

templatable 的代码中,compile 方法每次都调用 Handlebars.compile(template)(model),在每个实例初始化的时候都要编译一遍模板。这对于大部分情况下是很浪费CPU的,特别在ie下,批量渲染 DOM 的时候性能非常差。有改进的空间。

可以做缓存。

shaoshuai0102 commented 11 years ago

@lifesinger 刚才又测试了下 貌似 compile 方法不是特别耗费性能,反而套数据真正执行的时候比较耗性能。

seajs.use(['$', 'handlebars'], function($, Handlebars) {
    $(function() {
        var t1 = (new Date).getTime();
        for (var i = 0; i < 20; i++) {
            var t21 = (new Date).getTime();
            var r = Handlebars.compile('{{a}} {{b}} {{c}}{{a}} {{b}} {{c}}{{a}} {{b}} {{c}}{{a}} {{b}} {{c}}{{#c}}{{../a}}{{../b}}{{/c}}{{#c}}{{../a}}{{../b}}{{/c}}{{#c}}{{../a}}{{../b}}{{/c}}{{#c}}{{../a}}{{../b}}{{/c}}{{#c}}{{../a}}{{../b}}{{/c}}');
            var t22 = (new Date).getTime();

            r = r({
                a: 1,
                b: 2,
                c:3
                });
            var t23 = (new Date).getTime();
            //console.log(t22 - t21, t23 - t22, r);

        }
        var t2 = (new Date).getTime();
        alert(t2-t1);
    });
});

循环 20 次:

chrome 90ms 左右

ie6 625ms 左右

如果把后面的渲染 ·r = r {a...}· 去掉,基本上 compile 就不怎么费时间:

chrome 0

ie 0

囧了。我感觉不太科学,帮我看看测试用例有木有搞错。

leoner commented 11 years ago

chrome 100ms , ff 260ms 左右。按照你的这个测试代码呀!

leoner commented 11 years ago
seajs.use(['$', 'handlebars'], function($, Handlebars) {
    $(function() {
        var t1 = (new Date).getTime();
         var r = Handlebars.compile('{{a}} {{b}} {{c}}{{a}} {{b}} {{c}}{{a}} {{b}} {{c}}{{a}} {{b}} {{c}}{{#c}}{{../a}}{{../b}}{{/c}}{{#c}}{{../a}}{{../b}}{{/c}}{{#c}}{{../a}}{{../b}}{{/c}}{{#c}}{{../a}}{{../b}}{{/c}}{{#c}}{{../a}}{{../b}}{{/c}}');
        for (var i = 0; i < 20; i++) {
            var t21 = (new Date).getTime();         
            var t22 = (new Date).getTime();
            r({
                a: 1,
                b: 2,
                c:3
                });
            var t23 = (new Date).getTime();
            //console.log(t22 - t21, t23 - t22, r);

        }
        var t2 = (new Date).getTime();
        alert(t2-t1);
    });
});

@shaoshuai0102 你这个应该是把 Handlebars.compile 这个方法提到循环外来测试吧。如果提到循环外,也就是只有一次编译,然后连续渲染20次的话,刚才 FF 一下就降到了 19ms . chrome 才 9ms. 这样说明编译还是挺耗时的。

lifesinger commented 11 years ago

看起来还是 compile 的问题

我简单对比了一下 mustache、hogan、handlebars 目前 hogan 性能很不错

http://twitter.github.com/hogan.js/

语法基本上也够用,天杀的,难道真要换模板引擎?

On Wed, Mar 6, 2013 at 10:58 PM, hui.kang notifications@github.com wrote:

seajs.use(['$', 'handlebars'], function($, Handlebars) { $(function() { var t1 = (new Date).getTime(); var r = Handlebars.compile('{{a}} {{b}} {{c}}{{a}} {{b}} {{c}}{{a}} {{b}} {{c}}{{a}} {{b}} {{c}}{{#c}}{{../a}}{{../b}}{{/c}}{{#c}}{{../a}}{{../b}}{{/c}}{{#c}}{{../a}}{{../b}}{{/c}}{{#c}}{{../a}}{{../b}}{{/c}}{{#c}}{{../a}}{{../b}}{{/c}}'); for (var i = 0; i < 20; i++) { var t21 = (new Date).getTime(); var t22 = (new Date).getTime(); r({ a: 1, b: 2, c:3 }); var t23 = (new Date).getTime(); //console.log(t22 - t21, t23 - t22, r);

    }
    var t2 = (new Date).getTime();
    alert(t2-t1);
});

});

@shaoshuai0102 https://github.com/shaoshuai0102 你这个应该是把 Handlebars.compile 这个方法提到循环外来测试吧。如果提到循环外,也就是只有一次编译,然后连续渲染20次的话,刚才 FF 一下就降到了 19ms . chrome 才 9ms. 这样说明编译还是挺耗时的。

— Reply to this email directly or view it on GitHubhttps://github.com/aralejs/widget/issues/28#issuecomment-14503281 .

王保平 / 玉伯(射雕) 送人玫瑰手有余香

lepture commented 11 years ago

同意换,handlerbars 的版本烦死人

shaoshuai0102 commented 11 years ago

按照辉哥 @leoner 的方法我又试了下,确实还是 compile的问题。我待会把 calendar 的预编译加上,看看 calendar 渲染的效率会提高多少。

如果预编译能解决问题,建议还是不要换模板,换模板的代价好高。

shaoshuai0102 commented 11 years ago

刚才又测试了 calendar:两个日历连续渲染,测试第一个和第二个初始化的时间。

格式: 浏览器:time(1st)/time(2nd)

预编译版本

chrome 9/6 5/6 6/4 6/6 7/5 ie 31/47 63/62 63/78 62/94 78/93 94/109 109/205

未编译版本(但是又缓存)

chrome 21/4 14/6 14/4 25/8 13/5 17/7 ie 141/31 157/31 204/46 250/46 313/78 344/62 375/78 406/94

可以看到预编译可以明显提高性能,特别是ie下。如果没有预编译,缓存编译结果也可以提高除第一次之外的性能。

另外,在ie下越刷新越慢。不知道是什么原因

lepture commented 11 years ago

33

nuintun commented 11 years ago

@lifesinger artTemplate考虑过没有?还有Juicer,个人感觉artTemplate效率更好点。