JavaScript 性能提高之路

  在平时工做作项目的过程当中咱们有时候会遇到页面加载好久才加载出来的状况,这样严重影响了用户的体验效果。虽说有时候多是由于网络问题,但有些时候确实是前端代码没有足够优化致使的。因此经过查阅相关资料并实践后,总结出以下知识点来提高性能。有什么写得不对的地方还但愿各路大神指出并加以指点。javascript

一、数据访问

一、将全部script标签放在尽量接近body标签底部的位置,尽量减小对整个页面下载的影响。css

二、尽可能少用全局变量(解决办法:使用严格模式能够避免)。由于变量在做用域链中的位置越深,访问的时间就越长。局部变量位于做用域链中的第一个对象中,全局变量老是位于做用域链的最后一环,因此全局变量老是最慢的。
三、避免全局查询,若是必定要用到全局变量时,而且须要在某个函数中屡次用到该全局变量时,能够定义一个局部变量指向全局变量,来缩短在做用域链中的查询深度。html

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;
                }
            }
        }
    }
复制代码

四、将集合的length属性用一个局部变量来保存,在迭代中使用该变量。java

for (var j=0,len=track.length;j<len;j++) 
复制代码

四、避免使用with表达式,由于它增长做用域链的长度(with能够将一个没有或有多个属性的对象处理一个彻底隔离的词法做用域,同时定义在这个with块内部var声明会被添加早with所在的函数做用域中),with一般被当作重复引用同一个对象的多个属性的快捷方式,能够不须要重复引用对象自己。并且应当当心的对待try-catch的catch子句,它具备一样效果。 //例子1 var obj={ a:1, b:2, c:3 } //简单的快捷方式 with(obj){ a=2; b=3; c=4 }ajax

//例子2
    function foo(obj){
        with(obj){
            a=2;
        }
    }
    var obj1={
        a:1
    }
    var obj2={
        b:3
    }
    foo(obj1);
    console.log(obj1.a);//2
    foo(obj2);
    console.log(obj.a);//undefined
    console.log(a);//2  a被泄露到全局做用域上,with中只会对传入的对象属性进行修改,不能给对象添加新属性。
复制代码

五、一个属性或方法在原型链中的位置越深,它的访问速度就越慢。
六、声明变量时,多个变量合并声明,能够减小内存消耗。数组

var a;
    var b;
    var c;
    //推荐
    var a,b,c
复制代码

七、不要使用eval(功能是把对应的字符串解析成JS代码并运行),不安全,很是耗性能(2次,一次解析成js语句,一次执行),同时也会对eval()所在的词法做用域进行修改。浏览器

function foo(str,a){
        aval(str);//改变词法做用域
        console.log(a,b)
    }
    var b=2;
    foo("var b=3",1);
复制代码

八、利用图像灯标实现向服务器快速传送数据。格式:(new Image).src=url?params.join("&")。
九、用数组和对象的直接量建立对象和数组,比非直接量形式建立和初始化更快。缓存

var obj={};
    var arr=[];
复制代码

十、尽可能使用javascript自带的原生方法,如Math.abs()。
十一、避免重复进行相同操做。如须要检测浏览器时,使用延迟加载和条件预加载(?三元符) 延迟加载的代码以下:安全

function addhandler(target,eventType,handler){
    	if(target.addEventListener){
    		addhandler=function(){
    			target.addEventListener(eventType,handler,false);
    		};
    	}else{
    		addhandler=function(){	
    		    target.addEventListener("on"+eventType,handler)
    		};
    	}
    	addhandler(target,eventType,handler);
    }
    var dom=document.getElementById("test");
    addhandler(dom,"click",function(){
    	console.log("测试");
    })   
复制代码

十二、减小ajax的请求次数。 在服务器端,设置http头,确保返回报文被缓存在浏览器端(Expires头告诉浏览器应当缓存返回报文多长时间,其值是一个日期。超过这个日期发起请求后,都将从服务器获取数据。同时向文件名附加时间戳能够解决缓存问题。

格式:Expires: Mon, 28 Jul 2014 23:30:00 GM)。
复制代码

1三、使用内容传递网络(CDN——经过地理位置上最近的位置向用户提供服务,减小网络延迟)提供javascript文件,在提升性能的同时,还能够管理压缩和缓存。

二、Dom操做

  Dom(文档对象模型)是一个独立于语言的,使用xml和html文档操做的应用程序接口。在浏览器中的接口倒是以javascript来实现的。Dom和javascript当作两座岛,二者之间经过一座收费的桥链接。通常建议尽可能留在javascript岛上。

一、用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
复制代码

二、 若是统一个Dom元素或集合被访问一次以上,最好使用一个局部变量来缓存此Dom成员,在循环中使用局部变量缓存集合引用和集合元素会提高速度。
三、遍历children比childNodes更快。children不区分(包括)注释节点和空文本节点,因此快一些。
四、使用element.cloneNode(bool)复制节点,bool为false表示浅复制,只复制当前节点,bool为true时,表示深复制,还会复制其子节点。这种方式比document.createElement()速度要快一些。
五、 使用document.querySelector和document.querySelectorAll("div.warning,div.notice")来快速查找。由于它们返回一个NodeList——由符合条件的节点构成的类数组对象,而不是HTML集合(老是表现出存在性),避免了它所固有的性能问题(以及存在的逻辑问题)。querySelectorAll("div.warning,div.notice")还能够进行联合查询。
六、修改样式时,可使用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;'  
复制代码

七、尽可能避免写在HTML标签中写Style属性,使用外联样式便于维护和修改。
八、避免图片和iFrame等的空Src。空Src会从新加载当前页面,影响速度和效率。
九、采用事件委托。元素链接事件句柄会影响页面性能,采用委托利用事件冒泡的性能减小元素链接事件。(事件挂接过程都是发生在onload或DOMContentReady)事件中。
十、避免使用css表达式,避免使用高级选择器(如后代、伪类选择器),通配选择器。
十一、压缩文件(gzip),能够减小内存占用,同时减小查询时间。
十二、合并样式和脚本、使用css图片精灵(雪碧图)(这样作是为了减小向服务器的请求数量,从而达到性能优化的效果)。
1三、缩短页面的加载时间,先将页面结构显示出来,而后使用ajax获取剩下的重要文件。

三、循环

一、for-in是四种循环方法中速度最慢的一种,通常用于循环对象(须要查找自身属性仍是原型属性)。不建议循环数组。除非要迭代遍历一个属性未知的对象,不然通常不用for-in。
二、改变循环条件的顺序来提升循环性能。

//推荐
    for(var i=items.length;i--;){
        //todo
    }
    //不推荐
    for(var i=0,len=items.length;i<len;i++){
        //todo
    }   
复制代码

三、经过减小循环体来优化性能。

相关文章
相关标签/搜索