算法和流程控制的优化
var n = 10000000;
// 准备待测数组
var arr = [];
for(var count=0;count<n;count++){
arr[count] = 1;
}
// for 测试
console.time('for');
for(var i=0;i<arr.length;i++){
arr[i];
}
console.timeEnd('for');
image.png
总结:
1.能用for缓存的方法循环就用for循坏,性能最高,写起来繁杂;
2.不追求极致性能的情况下,建议使用forEach方法,干净,简单,易读,短,没有中间变量,没有成堆的分号,简单非常
优雅;
3.想尝鲜使用ES6语法的话,不考虑兼容性情况下,推荐使用for of方法,这是最简洁、最直接的遍历数组元素的语法,该方
法避开了for-in;循环的所有缺陷与forEach()不同的是,它可以正确响应break、continue和return语句.
4.能避免for in循环尽量避免,太消费性能,太费时间,数组循环不推荐使用.
更快速的数据访问
在局部作用域中访问全局变量需要一层一层遍历整个作用域链直至顶级作用域,而局部变量的访问效率则会更快更高,因此在局部作用域中高频率使用一些全局对象时可以将其导入到局部作用域中
//修改前
function showLi(){
var i = 0;
for(;i<document.getElementsByTagName("li").length;i++){ //一次访问document
console.log(i,document.getElementsByTagName("li")[i]); //三次访问document
};
};
//修改后
function showLi(){
var li_s = document.getElementsByTagName("li"); //一次访问document
var i = 0;
for(;i<li_s.length;i++){
console.log(i,li_s[i]); //三次访问局部变量li_s
};
};
再来看看两个简单的例子;
//1、作为参数传入模块
(function(window,$){
var xxx = window.xxx;
$("#xxx1").xxx();
$("#xxx2").xxx();
})(window,jQuery);
//2、暂存到局部变量
function(){
var doc = document;
var global = window.global;
}
DOM操作的优化
DOM操作远比javascript的执行耗性能
function innerLi_s(){
var i = 0;
for(;i<20;i++){
document.getElementById("Num").innerHTML="A";
//进行了20次循环,每次又有2次DOM元素访问:一次读取innerHTML的值,一次写入值
};
};
针对以上方法进行一次改写:
function innerLi_s(){
var content ="";
var i = 0;
for(;i<20;i++){
content += "A"; //这里只对js的变量循环了20次
};
document.getElementById("Num").innerHTML += content;
//这里值进行了一次DOM操作,又分2次DOM访问:一次读取innerHTML的值,一次写入值
};
减少页面的重排(Reflows)和重绘(Repaints)
浏览器下载完HTMl,CSS,JS后会生成两棵树:DOM树和渲染树。 当Dom的几何属性发生变化时,比如Dom的宽高,或者颜色,position,浏览器需要重新计算元素的几何属性,并且重新构建渲染树,这个过程称之为重绘重排。
元素布局的改变或内容的增删改或者浏览器窗口尺寸改变都将会导致重排,而字体颜色或者背景色的修改则将导致重绘。
对于类似以下代码的操作,据说现代浏览器大多进行了优化(将其优化成1次重排版):
//修改前
var el = document.getElementById("div");
el.style.borderLeft = "1px"; //1次重排版
el.style.borderRight = "2px"; //又1次重排版
el.style.padding = "5px"; //还有1次重排版
//修改后
var el = document.getElementById("div");
el.style.cssText = "border-left:1px;border-right:2px;padding:5px"; //1次重排版
针对多重操作,以下三种方法也可以减少重排版和重绘的次数:
- Dom先隐藏,操作后再显示 2次重排 (临时的display:none);
- document.createDocumentFragment() 创建文档片段处理,操作后追加到页面 1次重排;
- var newDOM = oldDOM.cloneNode(true)创建Dom副本,修改副本后oldDOM.parentNode.replaceChild
(newDOM,oldDOM)覆盖原DOM 2次重排 - 如果是动画元素的话,最好使用绝对定位以让它不在文档流中,这样的话改变它的位置不会引起页面其它元素重排
更多DOM优化的细节以及关于浏览器页面的重排(Reflows)和重绘(Repaints)的概念和优化请参考:天生就慢的DOM如何优化?,花10+分钟阅读,你会受益匪浅.
网友评论