资讯专栏INFORMATION COLUMN

用测试工具JSLitmus来告诉你几个提升JavaScript性能的小技巧

罗志环 / 838人阅读

摘要:性能测试工具操作测试代码测试结果黄条代表每秒可执行测试函数的次数,当然越多越快。务必减少操作,减少无意义的路径的查找。其他测试测试代码这些测试代码来自,官网的例子这是一个空的非循环测试。正则表达式测试,数组的,新建日期,稍微慢了些。

性能测试工具

JSLitmus

dom操作 测试代码
function domTestDepthOne () {
    document.getElementById("domTestWrap")
}
function domTestDepthOneQS () {
    document.querySelector("#domTestWrap")
}
function domTestDepthTwo () {
    document.getElementById("domTestWrap").getElementsByClassName("dom-test-content")
}
function domTestDepthTwoQSA () {
    document.querySelectorAll("#domTestWrap .dom-test-content")
}
function domTestDepthThree () {
    var domTestTextList = document.getElementById("domTestWrap").getElementsByClassName("dom-test-content")
    for (var i=0; i< domTestTextList.length; i++) {
        domTestTextList[i].innerHTML
    }
}
function domTestDepthThreeQSA () {
    var domTestTextList = document.querySelectorAll("#domTestWrap .dom-test-content")
    for (var i=0; i< domTestTextList.length; i++) {
        domTestTextList[i].innerHTML
    }
}
JSLitmus.test("dom test depth one", domTestDepthOne)
JSLitmus.test("dom test depth one query selecter", domTestDepthOneQS)
JSLitmus.test("dom test depth two", domTestDepthTwo)
JSLitmus.test("dom test depth two query selecter all", domTestDepthTwoQSA)
JSLitmus.test("dom test depth three query", domTestDepthThree)
JSLitmus.test("dom test depth three query selecter all", domTestDepthThreeQSA)
测试结果

PS:黄条代表每秒可执行测试函数的次数,当然越多越快。

分析总结

dom操作非常耗时,querySelector&querySelectorAll书写方便但相比

document.getElementById更加耗时些。务必减少dom操作,减少无意义的dom路径的查找。

对象操作 测试代码
var objectTest = {
    one : {
        name: "one",
        value: 1,
        two: {
            name: "two",
            value: 2,
            three: {
                name: "three",
                value: 3
            }
        }
    }
}

var three = objectTest.one.two.three;
function objectTestDepthZero () {
    three.name
    three.value
}

function objectTestDepthThree () {
    objectTest.one.two.three.name
    objectTest.one.two.three.value
}


JSLitmus.test("object test depth zero", function (count) {
    while (count -- ) objectTestDepthZero()
})
JSLitmus.test("object test depth three", function (count) {
    while (count -- ) objectTestDepthThree()
})
测试结果

分析总结

对象属性的访问非常耗时,原因于JavaScript引擎内部存储变量的结构有关,JavaScript是弱类型语言,它不像强类型语言如C、C++那样可以通过内存地址偏移来快速访问。

可以参考,用最简单易懂的道理告诉你,为什么JavaScript在现代引擎(V8,JavaScriptCore)下,能表现出卓越性能!

务必减少对象嵌套的深度,减少无意义的对象路径的查找

作用域冒泡 测试代码

测试代码来自JSLitmus官网主页的例子

// 很多开发者不知道变量作用域对于脚本的性能有多少影响。
// 为了直观地展示这一点,我们写了下面的JSLitmus测试用例去测量对定义在不同作用域下的变量
// 执行"递增(++)"操作的表现

// 首先,测试定义在全局作用域的变量
var global_var = 1;
JSLitmus.test("global", function(count) {
  while (count--) global_var++;}
);

// 现在测试一个定义在局部函数作用域的变量
JSLitmus.test("local", function(count) {
  var local_var = 1;
  while (count--) local_var++;
});

// 尝试测试一个绑定到立即执行函数内的变量。
// 喜欢Prototype和JQuery的开发者应该觉得这样特别有意思
JSLitmus.test("closure",
  (function() {
    var closure_var = 1;
    return function(count) {while (count--) closure_var++;}
  })()
);

// 还是绑定在立即执行函数中的变量,不过这次套了两层
JSLitmus.test("multi-closure",
  (function() {
    var multi_var = 1;
    return (function() {
      return function(count) {while (count--) multi_var++;}
    })()
  })()
);

// 测试一个空的函数调用,这可以作为一个参照点
JSLitmus.test("empty function call", function(count) {
  var f = function() {};
  while (count--) f();
});
测试结果

分析总结

每次访问变量或者函数都会进行一次作用域冒泡的过程,所以本地作用域如函数作用域是最快的,全局作用域最慢。
应该要尽量减少这个冒泡的层数,对于要经常访问的全局变量,应该在本地作用域做一个缓存。

其他测试 测试代码

这些测试代码来自,JSLitmus官网的例子

// 这是一个空的非循环测试。它的结果应该是一秒可以做无限次,或者非常接近无限的一个值
JSLitmus.test("empty test (non-looping)", function() {});

// 这是一个空的循环测试,对于这种执行非常快的代码,需要执行更多次才能得到比较准确的结果
// 所以经常使用循环测试
// 它的结果应该是一秒可以做无限次,或者非常接近无限的一个值
JSLitmus.test("empty test", function(count) {
  while (count--);
});

// 测试调用一个定义在全局作用域的函数的消耗
var emptyFunction = function() {};
JSLitmus.test("function overhead (non-looping)", function() {
  emptyFunction();
});

// 循环测试调用一个定义在本地作用域函数的消耗。
// 这个应该比前者更快,一个原因是使用循环测试更准确,另一个原因是函数定义在本地作用域了
JSLitmus.test("function overhead", function(count) {
  var f = emptyFunction;
  while (count--) f();
});

// 测试Array.join()方法,然后我们可以看看它和字符串"+"操作的对比
JSLitmus.test(""hello" + "world" (non-looping)", function() {
  var a = "hello", b = "world", x;
  x = a+b;
});

// 循环测试Array.join()方法,然后我们可以看看它和字符串"+"操作的对比
JSLitmus.test(""hello" + "world"", function(count) {
  var a = "hello", b = "world", x;
  while(count--) x = a+b;
});

// 循环测试Array.join()方法,然后我们可以看看它和字符串"+"操作的对比
JSLitmus.test("string join()", function(count) {
  var a = ["hello", "world"];
  while (count--) a.join();
});

// Math.random()是快还是慢呢?
JSLitmus.test("Math.random()", function(count) {
  while (count--) Math.random();
});

// 正则表达测试有多快呢?让我们来一探究竟
JSLitmus.test("RegExp.test()", function(count) {
  while (count--) /rl/.test("hello world");
});

// 呵呵,如果在循环的外面定义正则表达式对象会有帮助吗?
JSLitmus.test("cached RegExp.test()", function(count) {
  var re = /rl/;
  while (count--) re.test("hello world");
});

// 新建Date对象的速度怎样?是快还是慢?
JSLitmus.test("new Date()", function(count) {
  while (count--) new Date();
});

// 如果我们把Dete对象设置到元素的innerHTML中的速度如何?
// 因为这个操作一定很慢,所以就不需要循环测试了
JSLitmus.test("set Element.innerHTML", function() {
  document.getElementById("test_element").innerHTML = new Date();
});

// 测试一个数组的创建,这个可以作为一个参照物
JSLitmus.test("new Array()", function(count) {
  while (count--) {var a = [];}
});
测试结果

分析总结

图中,Infinity的测试代表非常快,其中,空函数的调用,字符串的"+"的拼接都非常快。
Math.random()与新建一个数组也比较快。
正则表达式测试,数组的join,新建日期,稍微慢了些。
最后,设置innerHTML的dom操作最慢。

更多

web性能优化--高性能javascript

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/80433.html

相关文章

  • HTML-CSS-JS

    摘要:本周于上海闭幕,掘金和知乎上都有对应的实录和问答,但会议的视频目前都还没放出来,有心的同学如果找到了欢迎分享。建议中英文对照阅读。英文原文前端独立技术博客推荐推荐一些现在还在坚持原创的博主,有业界大牛,也有小鲜肉,也有国外美女。 CSS 样式书写规范最佳实践 本文的所列是实践当中得出的一套比较不错的 CSS 书写规范,可以结合自身团队发展出一套适合自己业务的规范。 CSS中的字体与排版...

    mikasa 评论0 收藏0
  • HTML-CSS-JS

    摘要:本周于上海闭幕,掘金和知乎上都有对应的实录和问答,但会议的视频目前都还没放出来,有心的同学如果找到了欢迎分享。建议中英文对照阅读。英文原文前端独立技术博客推荐推荐一些现在还在坚持原创的博主,有业界大牛,也有小鲜肉,也有国外美女。 CSS 样式书写规范最佳实践 本文的所列是实践当中得出的一套比较不错的 CSS 书写规范,可以结合自身团队发展出一套适合自己业务的规范。 CSS中的字体与排版...

    李世赞 评论0 收藏0
  • HTML-CSS-JS

    摘要:本周于上海闭幕,掘金和知乎上都有对应的实录和问答,但会议的视频目前都还没放出来,有心的同学如果找到了欢迎分享。建议中英文对照阅读。英文原文前端独立技术博客推荐推荐一些现在还在坚持原创的博主,有业界大牛,也有小鲜肉,也有国外美女。 CSS 样式书写规范最佳实践 本文的所列是实践当中得出的一套比较不错的 CSS 书写规范,可以结合自身团队发展出一套适合自己业务的规范。 CSS中的字体与排版...

    MudOnTire 评论0 收藏0
  • 程序员练级攻略(2018):前端性能优化和框架

    摘要:,谷歌给的一份性能指南和最佳实践。目前而言,前端社区有三大框架和。随后重点讲述了和两大前端框架,给出了大量的文章教程和相关资源列表。我认为,使用函数式编程方式,更加符合后端程序员的思路,而是更符合前端工程师习惯的框架。 showImg(https://segmentfault.com/img/bVbjQAM?w=1142&h=640); 这个是我订阅 陈皓老师在极客上的专栏《左耳听风》...

    VEIGHTZ 评论0 收藏0
  • 程序员练级攻略(2018):前端性能优化和框架

    摘要:,谷歌给的一份性能指南和最佳实践。目前而言,前端社区有三大框架和。随后重点讲述了和两大前端框架,给出了大量的文章教程和相关资源列表。我认为,使用函数式编程方式,更加符合后端程序员的思路,而是更符合前端工程师习惯的框架。 showImg(https://segmentfault.com/img/bVbjQAM?w=1142&h=640); 这个是我订阅 陈皓老师在极客上的专栏《左耳听风》...

    CoffeX 评论0 收藏0

发表评论

0条评论

罗志环

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<