引擎渲染速度测试--我js代码写得少你不要骗我

上一张图,很多人都看过的

地址:http://aui.github.io/artTemplate/test/test-speed.html

这个地址是在看artTemplate的时候看到的,很早都看过但是没去研究为什么artTemplate为什么那么快,其他的为什么那么慢。最近看underscore的源码,先看了template部分,再想起这张图,我就不服了。凭神马underscore那么慢,基本上就是倒数第二的成绩。我代码写得少,上面那个图是在骗我吗!!!

于是看了下作者的测试代码,也在作者那个页面跑了好几次,结果几乎都差不多,难道事实就是这样的!!!!underscore的渲染速度是垫底的成绩。于是看了看作者的测试代码,其他的不管,只看underscore的。

 name: ‘underscoreTemplate‘,
        tester: function () {
            var source = document.getElementById(‘underscoreTemplate‘).innerHTML;
            var fn = _.template(source);
            for (var i = 0; i < number; i ++) {
                fn(data);
            }
        }

页面上还有一些变量

// 数据量
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‘
    });
};

模板代码

<!-- 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>

以上代码貌似都没什么看头,都是正常的使用代码,但是我想说underscore可以这样用var fn = _.template(source,{variable:list});您也可以在 variable 设置里指定一个变量。名外部指定变量名内部就不会使用with,问题就出在这里,测试代码没这样用!!!!

其实underscore内部代码稍加改动就可以去掉with。于是我把代码稍加改动,使用方式稍加改动,以下是改后的代码。 我使用的underscore的版本是1.7.0

    // JavaScript micro-templating, similar to John Resig‘s implementation.
    // Underscore templating handles arbitrary delimiters, preserves whitespace,
    // and correctly escapes quotes within interpolated code.
    // NB: `oldSettings` only exists for backwards compatibility.
    // template本身是一个方法,可以提供三个参数,第一个为模板文本,第二个为对应模板数据,第三个为基本配置信息
    //模板函数可以使用 <%= … %>插入变量, 也可以用<% … %>执行任意的 JavaScript 代码、进行HTML转义,使用<%- … %>
    _.template = function(text, settings, oldSettings) {
        if (!settings && oldSettings) settings = oldSettings;
        settings = _.defaults({}, settings, _.templateSettings);

        // Combine delimiters into one regular expression via alternation.
        var matcher = RegExp([
            (settings.escape || noMatch).source, (settings.interpolate || noMatch).source, (settings.evaluate || noMatch).source
        ].join(‘|‘) + ‘|$‘, ‘g‘);

        // Compile the template source, escaping string literals appropriately.
        var index = 0;
        var source = "__p+=‘";
        //没有设置settings.variable 默认使用对象+. 来取值
        var settingObj = !!settings.variable ? ‘‘ : ‘_obj.‘;
        //几个分组
        text.replace(matcher, function(match, escape, interpolate, evaluate, offset) {
            source += text.slice(index, offset).replace(escaper, escapeChar);
            index = offset + match.length;

            if (escape) {
                //编码
                //_obj.XXX
                source += "‘+\n((__t=(" + settingObj + escape.trim() + "))==null?‘‘:_.escape(__t))+\n‘";
            } else if (interpolate) {
                //取值
                //_obj.XXX
                source += "‘+\n((__t=(" + settingObj + interpolate.trim() + "))==null?‘‘:__t)+\n‘";
            } else if (evaluate) {
                //任意的Javascript
                source += "‘;\n" + evaluate + "\n__p+=‘";
            }
            // Adobe VMs need the match returned to produce the correct offest.
            return match;
        });
        source += "‘;\n";

        // If a variable is not specified, place data values in local scope.
        // 据说使用with 性能不咋地,可以使用变量        // with可能会影响性能,并造成难以发现的错误
        //if (!settings.variable) source = ‘with(obj||{}){\n‘ + source + ‘}\n‘;
        //去掉使用with
        if (!settings.variable) source = ‘ var _obj=obj||{};\n‘ + source + ‘ \n‘;
        source = "var __t,__p=‘‘,__j=Array.prototype.join," +
            "print=function(){__p+=__j.call(arguments,‘‘);};\n" +
            source + ‘return __p;\n‘;

        try {
            var render = new Function(settings.variable || ‘obj‘, ‘_‘, source);
        } catch (e) {
            e.source = source;
            throw e;
        }

        var template = function(data) {
            return render.call(this, data, _);
        };

        // Provide the compiled source as a convenience for precompilation.
        var argument = settings.variable || ‘obj‘;
        template.source = ‘function(‘ + argument + ‘){\n‘ + source + ‘}‘;

        return template;
    };

改动后的代码,加上使用也改动下,指定variable,测试结构大变,修改后测试结构如下图。不是underscore慢,是没用对。不信自己跑一跑 我提供代码。下载地址:test.zip 里面有一个test-speed.html  跑一下就知道结果了。

这是在chrome38中的测试结果

这是在firefox 34中的测试效果

模板引擎基本上都是模板先预编译 fn = _.template(source),然后调用之前得到的函数fn(data)进行最后的渲染。所以模板引擎的速度应该是模板预编编译时间和数据渲染时间之和才对,但是这里只测试了一个渲染数据的时间,明显不够全面。

我也测试了一下编译速度,发现最快的Handlebars,而artTemplate速度基本上处于垫底水平,不信自己测试。最后得出:模板预编译时间加上渲染的速度其实artTemplate并不是想象中那么快,其实和underscore差不多。不信自己测试下。

时间: 2024-07-31 08:28:07

引擎渲染速度测试--我js代码写得少你不要骗我的相关文章

appium js代码写的H5寻找元素点击方法

java写发 p.p1 { margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Monaco } p.p2 { margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Monaco; min-height: 15.0px } span.s1 { color: #931a68 } span.s2 { color: #7e504f } span.Apple-tab-span { white-space: pre } publ

代码写的少,搞不清边界和起始

1 for(p = fmt; *p; p++) 2 { 3 if(*p != '%') 4 { 5 putchar(*p); 6 continue; 7 } 8 i = 0;// 永远指向下一个字符,因为0时也没有字符,可能最终也是没有字符 9 localfmt[i++]='%'; // start local fmt 10 while( *(p+1) && !isalpha(*(p+1)) ) // p 只处理到当前字符 测试下一字符 ++p 测试 p+1 11 // i 处理到下一字符

试着讲清楚:js代码运行机制

一. js运行机制 js执行引擎 经常看文章的说到js是带线程的,其实这个说法非常的模糊,准确的是js执行引擎是单线程的,js执行引擎就是js代码的执行器,有了这个概念就可以下来说说js是如何运行的了. js代码如何运行? 在js代码执行的时候,js的代码是按照顺序执行的,从上到下,这个时候是同步的,不过,有几个例外: 异步的网络请求 事件绑定.事件监听器 时间触发函数 我们模拟一下,js引擎遇到这三类代码的情况: js执行的好好的,正在顺序执行代码,这个时候呢,遇到了异步的网络请求的代码,这个

轮播图--JS手写

轮播图基本每个网站都会有,也有很多的JQuery插件可以用,这里是用JS代码写的. @{ Layout = null; } <!DOCTYPE html> <html> <head> <meta name="viewport" content="width=device-width" /> <title>Test</title> <script src="~/Scripts/jq

ASP.NET服务器端向客户端注册JS代码的方法总结

一.用Response.Write方法 这种方法会把JS代码写在页面的最顶部(<html>的前面) 代码如下:Response.Write("<script type='text/javascript'>alert("XXX");</script>");此方法缺陷就是不能调用脚本文件中的自定义的函数,只能调用内部函数,具体调用自定义的函数只能在Response.Write写上函数定 义,比如Response.Write("

1在html中添加js代码的三种方式

1.第一种方式:在时间句柄后太假js代码: 例如浏览器弹出对话框; 1 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" 2 "http://www.w3.org/TR/html4/loose.dtd"> 3 <html> 4 <head> 5 <meta http-equiv="Content-Type" content=&qu

程序员面试京东前端,现场JavaScript代码写出魔方特效

程序员面试京东前端,现场JS代码写出魔方特效,成功搞定20K月薪 今天小编我逛论坛,看到了一位程序员小伙子,因为是有了两年工作经验,然后去京东面试前端岗,一面二面轻松就过了,到了技术面这一块,小伙干脆就直接用JavaScript写了一个魔方特效,最终通过了面试,试用期12K,转正20K的工资水平,这特效看的小编也服气,主要是脑洞大,所以我也COPY了一份源码,分享给头条上的小伙伴学习. 完成之后的效果图如图所示: 完整源码分享给大家: 想要更多项目源码拿来练练手的可以复制下方群号→ web前端/

js_ 预解析(js代码如何执行的)

1.要理解js代码是如何执行的 js代码是由  浏览器的 js解析引擎  来执行的,js代码执行(从上往下)之前要先预解析 js代码执行  :  同步.异步   (异步要等同步代码都执行完后再执行:异步的代码放在栈中等待同步代码从上往下全部执行完成之后再执行) 预解析  :作用 注意:定义函数中的 用函数表达式方式里只存在变量名提升,没有匿名函数提升 1.变量提升 2.函数提升 案例1: 案例2: 案例3: 原文地址:https://www.cnblogs.com/yangyutian/p/10

浏览器渲染引擎,提高css渲染速度。

一.渲染引擎渲染引擎的职责是……渲染,也就是把请求的内容显示到浏览器屏幕上.默认情况下渲染引擎可以显示HTML,XML文档以及图片. 通过插件(浏览器扩展)它可以显示其它类型文档. 二.各种渲染引擎我们提到的Firefox, Safari两种浏览器构建于两种渲染引擎之上:Firefox使用Gecko —— Mozilla自家的渲染引擎:Safari 和 Chrome 都使用 Webkit. 最终决定浏览器表现出来的页面效果的差异是:渲染引擎 Rendering Engine(也叫做排版引擎),也