JavaScript 性能提升之路(推荐)
作者:慕斯不想说话
在平时工作做项目的过程中我们有时候会遇到页面加载很久才加载出来的情况,这样严重影响了用户的体验效果。虽然说有时候可能是因为网络问题,但有些时候确实是前端代码没有足够优化导致的。所以通过查阅相关资料并实践后,总结出如下知识点来提升性能。有什么写得不对的地方还希望各路大神指出并加以指点。
1、数据访问
1、将所有script标签放在尽可能接近body标签底部的位置,尽可能减少对整个页面下载的影响。
2、尽量少用全局变量。因为变量在作用域链中的位置越深,访问的时间就越长。局部变量位于作用域链中的第一个对象中,全局变量总是位于作用域链的最后一环,所以全局变量总是最慢的。
3、避免全局查询,如果一定要用到全局变量时,并且需要在某个函数中多次用到该全局变量时,可以定义一个局部变量指向全局变量,来缩短在作用域链中的查询深度。
function addTotrackData(){ var allChildrenNode=getAllChildrenDepartmentNodes(); for (var i = 0; i < allChildrenNode.length; i++) { for (var j=0,len=track.length;j<len;j++) { if (trackNode[j]["userId"] == allChildrenNode[i]) { trackNode[j]["isOnMap"] = true; } } } }
上面代码可以改写为如下所示
function addTotrackData(){ var allChildrenNode=getAllChildrenDepartmentNodes(); var track=trackNode; for (var i = 0; i < allChildrenNode.length; i++) { for (var j=0,len=track.length;j<len;j++) { if (track[j]["userId"] == allChildrenNode[i]) { track[j]["isOnMap"] = true; } } } }
4、将集合的length属性用一个局部变量来保存,在迭代中使用该变量。
for (var j=0,len=track.length;j<len;j++)
5、避免使用with表达式,因为它增加作用域链的长度。而且应当小心的对待try-catch的catch子句,它具有同样效果。
6、一个属性或方法在原型链中的位置越深,它的访问速度就越慢。
7、声明变量时,多个变量合并声明,可以减少内存消耗。
var a; var b; var c; //推荐 var a,b,c
2、Dom操作
Dom(文档对象模型)是一个独立于语言的,使用xml和html文档操作的应用程序接口。在浏览器中的接口却是以javascript来实现的。Dom和javascript看成两座岛,两者之间通过一座收费的桥连接。一般建议尽量留在javascript岛上。
1、用innerHTML代替DOM操作,减少DOM操作次数,优化javascript性能。
//dom方式 var str="" var dom=document.getElementById("test"); var start1=new Date(); for(var j=0;j<100000;j++){ var div=document.createElement("div"); div.innerText="test"; dom.append(div); } var end1=new Date(); console.log("dom方式:"+(end1-start1));//dom方式:356 //inerHTML方式 var content=""; var start=new Date(); for(var i=0;i<10000;i++){ content=content+"<div>test</div>"; } document.getElementById("test").innerHTML=content; var end=new Date(); console.log("innerHTML方式:"+(end-start));//innerHTML方式:35
2、如果统一个Dom元素或集合被访问一次以上,最好使用一个局部变量来缓存此Dom成员,在循环中使用局部变量缓存集合引用和集合元素会提升速度。
3、遍历children比childNodes更快。children不区分(包括)注释节点和空文本节点,所以快一些。
4、使用element.cloneNode(bool)复制节点,bool为false表示浅复制,只复制当前节点,bool为true时,表示深复制,还会复制其子节点。这种方式比document.createElement()速度要快一些。
5、使用document.querySelector和document.querySelectorAll("div.warning,div.notice")来快速查找。因为它们返回一个NodeList——由符合条件的节点构成的类数组对象,而不是HTML集合(总是表现出存在性),避免了它所固有的性能问题(以及存在的逻辑问题)。querySelectorAll("div.warning,div.notice")还可以进行联合查询。
6、修改样式时,可以使用div.style.cssText来一起修改样式,或者使用类来修改(便于维护)。
var el = document.getElementById('mydiv'); //修改3次Dom el.style.borderLeft = '1px'; el.style.borderRight = '2px'; el.style.padding = '5px'; //推荐只需要修改1次Dom el.style.cssText = 'border-left: 1px; border-right: 2px; padding: 5px;'
7、尽量避免写在HTML标签中写Style属性,使用外联样式便于维护和修改。
8、避免图片和iFrame等的空Src。空Src会重新加载当前页面,影响速度和效率。
9、采用事件委托。元素连接事件句柄会影响页面性能,采用委托利用事件冒泡的性能减少元素连接事件。(事件挂接过程都是发生在onload或DOMContentReady)事件中。
3、循环
1、for-in是四种循环方法中速度最慢的一种,一般用于循环对象(需要查找自身属性还是原型属性)。不建议循环数组。除非要迭代遍历一个属性未知的对象,否则一般不用for-in。
2、改变循环条件的顺序来提高循环性能。
//推荐 for(var i=items.length;i--;){ //todo } //不推荐 for(var i=0,len=items.length;i<len;i++){ //todo }
3、通过减少循环体来优化性能。
以上所述是小编给大家介绍的JavaScript性能提升详解整合,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对脚本之家网站的支持!