自从JavaScript诞生以来,用这门语言编写网页的开发人员有了极大的增长。与此同时,JavaScript代码的执行效率也越来越受到关注。只因JavaScript是一种解释型语言,执行速度要比编译型语言慢的多。虽然很多主流的浏览器陆续实现了JavaScript的编译执行,不过还是有些方法可以改进代码的整体性能的
- 避免全局查找
优化脚本性能最重要的就是注意全局查找。全局变量和函数肯定要比局部的开销更大,因为涉及作用域链上的查找
function updateUI() {
var imgs = document.getElementsByTagName("img");
for (var i=0, len=imgs.length; i < len; i++){
imgs[i].title = document.title + " image " + i;
}
var msg = document.getElementById("msg");
msg.innerHTML = "Update complete.";
}
大家仔细观察一下,这就是我们平时写的函数对不对,很正常,没有什么问题;但是它包含了三个对于全局document对象的引用。如果页面上有多个图片,那么for循环中的document引用就会被执行多次甚至上百次,每次都需要作用域链去查找,就会影响性能。我们可以修改成一下方式:
function updateUI() {
var doc = documnet;
var imgs = doc.getElementsByTagName("img");
for (var i=0, len=imgs.length; i < len; i++){
imgs[i].title = doc.title + " image " + i;
}
var msg = document.getElementById("msg");
msg.innerHTML = "Update complete.";
}
这里,首先将document对象保存在本地的doc变量中;然后在余下的代码中替换原来的document。与原来相比,现在的函数只有一次全局查找,肯定更快
总结:将在一个函数中会用到多次的全局对象存储为局部局部变量总是没有错的啦
- 避免with语句
在性能非常重要的地方一定要避免witch语句。和函数相类似,with语句会创建自己的作用域,因此会增加执行的代码的作用域的长度。由于额外的作用域链查找,在with语句中执行的代码肯定会比外面的代码要慢 - 避免不必要的属性查找
我们平时在定义一个变量的时候,会这样写:
var value = [5,10]
var sum = values[0] + values[10]
使用变量和数组要比访问对象上的属性更加有效率,因为对象是一个O(n)操作,对象上的任何属性查找都要比访问变量或者数组花费更长的时间,因为必须在原型链中对拥有改名称的属性进行一次搜索。其实就是属性查找越多,执行时间越长。如果我们写成这样:
var values = {first: 5, second: 10};
var sum = values.first + values.second;
这段代码使用了两次属性查找来计算sum的值。其实进行一两次属性查找并不会导致显著的性能问题,但是次数多了就会减慢执行速度,所以最好不要用这样的方法。
你再比如说这样的写法:
var query = window.location.href.substring(window.location.href.indexOf("?"))
通过上面的代码,我们可以看出有6次属性查找;window.location.href.substring有3次属性查找,window.location.href.indexOf有三次属性查找,只要通过数点的数量我们就知道查找次数了。这段代码都用到了window.location.href,这样进行两次查找,效果特别不好。所以我们可以改成这样:
var url = window.location.href;
var query = url.substring(url.indexOf("?"));
这样写的话,查找次数就会减少到4次,相比上个版本减少到33%。
通过这样简单的优化,会为我们的项目性能提升很多,接下来会继续从性能优化方面剖析