??xml version="1.0" encoding="utf-8" standalone="yes"?>欧美麻豆精品久久久久久,久久精品超碰,天堂在线免费avhttp://www.aygfsteel.com/xiaohuzi2008/category/53425.html面朝大vQ春暖花开zh-cnFri, 05 Apr 2013 04:39:00 GMTFri, 05 Apr 2013 04:39:00 GMT60【{?Javascript执行效率结http://www.aygfsteel.com/xiaohuzi2008/archive/2013/04/04/397393.html胡?/dc:creator>胡?/author>Thu, 04 Apr 2013 15:20:00 GMThttp://www.aygfsteel.com/xiaohuzi2008/archive/2013/04/04/397393.htmlhttp://www.aygfsteel.com/xiaohuzi2008/comments/397393.htmlhttp://www.aygfsteel.com/xiaohuzi2008/archive/2013/04/04/397393.html#Feedback0http://www.aygfsteel.com/xiaohuzi2008/comments/commentRss/397393.htmlhttp://www.aygfsteel.com/xiaohuzi2008/services/trackbacks/397393.html

Javascript是一门非常灵zȝ语言Q我们可以随心所Ʋ的书写各种风格的代码,不同风格的代码也必然也会(x)D执行效率的差异,开发过E中雉散散地接触到许多提高代码性能的方法,整理一下^时比较常见ƈ且容易规避的问题

Javascript自n执行效率

Javascript中的作用域链、闭包、原型ѝeval{特性,在提供各U神奇功能的同时也带来了各种效率问题Q用之不慎就?x)导致执行效率低下?/p>

1、全局导入

我们在编码过E中多多少?x)用到一些全局变量Qwindow,document,自定义全局变量{等Q,了解javascript作用域链的h?知道Q在局部作用域中访问全局变量需要一层一层遍历整个作用域铄至顶U作用域Q而局部变量的讉K效率则会(x)更快更高Q因此在局部作用域中高频率使用一些全 局对象时可以将其导入到局部作用域中,例如Q?/p>

 1 //1、作为参C入模?/span>
 2 (function(window,$){
 
3     var xxx = window.xxx;
 
4     $("#xxx1").xxx();
 
5     $("#xxx2").xxx();
 
6 })(window,jQuery);
 
7 
 
8 //2、暂存到局部变?/span>
 9 function(){
10     var doc = document;
11     var global = window.global;
12 }

2、eval以及(qing)ceval问题

我们都知道eval可以一D字W串当做js代码来执行处理,据说使用eval执行的代码比不用eval的代码慢100倍以上(具体效率我没有测试,有兴同学可以测试一下)

JavaScript 代码在执行前?x)进行类?#8220;预编?#8221;的操作:(x)首先?x)创Z个当前执行环境下的活动对象,q将那些?var x的变量设|ؓ(f)zd对象的属性,但是此时q些变量的赋值都?undefinedQƈ那些以 function 定义的函Cd为活动对象的属性,而且它们的值正是函数的定义。但是,如果你用了“eval”Q则“eval”中的代码Q实际上为字W串Q无法预先识 别其上下文,无法被提前解析和优化Q即无法q行预编译的操作。所以,其性能也会(x)大幅度降?/p>

其实现在大家一般都很少?x)用eval了,q里我想说的是两个类eval的场?new Function{},setTimeout,setInterver)


setTimtout("alert(1)",1000);

setInterver(
"alert(1)",1000);

(
new Function("alert(1)"))();

上述几种cd代码执行效率都会(x)比较低,因此直接传入匿名Ҏ(gu)、或者方法的引用lsetTimeoutҎ(gu)

3、闭包结束后释放掉不再被引用的变?/h2>


var f = (function(){
    
var a = {name:"var3"};
    
var b = ["var1","var2"];
    
var c = document.getElementByTagName("li");
    
//****其它变量
    //***一些运?/span>
    var res = function(){
        alert(a.name);
    }
    
return res;
})()

上述代码中变量f的返回值是׃个立x行函数构成的闭包中返回的Ҏ(gu)resQ该变量保留了对于这个闭包中所有变量(a,b,c{)的引用,因此q两个变 量会(x)一直驻留在内存I间?其是对于dom元素的引用对内存的消耗会(x)很大Q而我们在res中只使用Ca变量的|因此Q在闭包q回前我们可以将其它?量释?/div>
var f = (function(){
    
var a = {name:"var3"};
    
var b = ["var1","var2"];
    
var c = document.getElementByTagName("li");
    
//****其它变量
    //***一些运?/span>
    //闭包q回前释放掉不再使用的变?/span>
    b = c = null;
    
var res = function(){
        alert(a.name);
        }
    
return res;
})()

在web开发过E中Q前端执行效率的瓉往往都是在dom操作上面Qdom操作是一件很耗性能的事情,如何才能在dom操作q程中尽量节U性能呢?

1、减reflow

什么是reflowQ?/h3>

?DOM 元素的属性发生变?(?color) ? 览器会(x)通知 render 重新描绘相应的元? 此过E称?repaint?/p>

如果该次变化涉及(qing)元素布局 (?width), 览器则抛弃原有属? 重新计算q把l果传递给 render 以重新描l页面元? 此过E称?reflow?/p>

减少reflow的方?/h3>
  1. 先将元素从document中删除,完成修改后再把元素放回原来的位置Q当Ҏ(gu)元素?qing)其子元素进行大量reflow操作Ӟ1,2两种Ҏ(gu)效果才会(x)比较明显Q?/p>

  2. 元素的display讄?#8221;none”Q完成修改后再把display修改为原来的?/p>

  3. 修改多个样式属性时定义classcM替多ơ修改style属性(for certain同学推荐Q?/li>
  4. 大量d元素到页面时使用documentFragment

例如


for(var i=0;i<100:i++){
    
var child = docuemnt.createElement("li");
    child.innerHtml 
= "child";
    document.getElementById(
"parent").appendChild(child);
}

上述代码?x)多ơ操作domQ效率比较低Q可以改Z面的形式 创徏documentFragmentQ将所有元素加入到docuemntFragment不会(x)改变doml构Q最后将其添加到面Q只q行了一ơreflow

var frag = document.createDocumentFragment();
for(var i=0;i<100:i++){
        
var child = docuemnt.createElement("li");
        child.innerHtml 
= "child";
    frag.appendChild(child);
}
document.getElementById(
"parent").appendChild(frag);

2、暂存dom状态信?/h2>

当代码中需要多ơ访问元素的状态信息,在状态不变的情况下我们可以将其暂存到变量中,q样可以避免多次讉Kdom带来内存的开销Q典型的例子是Q?/p>


var lis = document.getElementByTagName("li");
for(var i=1;i<lis.length;i++){
    
//***
}
上述方式?x)在每一ơ@环都去访问dom元素Q我们可以简单将代码优化如下
var lis = document.getElementByTagName("li");
for(var i=1,j=lis.length ;i<j;i++){
    
//***
}

3、羃?yu)选择器的查找范围

查找dom元素时尽量避免大面积遍历面元素Q尽量用精准选择器,或者指定上下文以羃?yu)查找范_(d)以jqueryZ

  • 用模糊匚w的选择器:(x)例如$("[name*='_fix']")Q多用诸如id以及(qing)逐步~小范围的复合选择?code>$("li.active"){?/li>
  • 指定上下文:(x)例如$("#parent .class")Q?code>$(".class",$el){?/li>

4、用事件委?/h2>

使用场景Q?/strong>一个有大量记录的列表,每条记录都需要绑定点MӞ在鼠标点d实现某些功能Q我们通常的做法是l每条记录都l定监听事gQ这U做法会(x)D面?x)有大量的事件监听器Q效率比较低下?/p>

基本原理Q?/strong>我们都知道dom规范中事件是?x)冒泡的Q也是说在不主动阻止事件冒泡的情况下Q何一个元素的事g??x)按照dom?wi)的l构逐冒至顶端。而event对象中也提供了event.targetQIE下是srcElementQ指向事件源Q因此我们即使在 父元素上监听该事g也可以找到触发该事g的最原始的元素,q就是委托的基本原理。废话不多说Q上CZ


$("ul li").bind("click",function(){
    alert($(
this).attr("data"));
})

上述写法其实是给所有的li元素都绑定了click事g来监听鼠标点?yn)L一个元素的事gQ这样页面上?x)有大量的事件监听器?/p>

Ҏ(gu)上面介绍的监听事件的原理我们来改写一?/p>


$("ul").bind("click",function(e){
    
if(e.target.nodeName.toLowerCase() ==="li"){
        alert($(e.target).attr(
"data"));
    }
})

q样一来,我们可以只d一个事件监听器Lh有li上触发的事gQƈ做出相应的操作?/p>

当然Q我们不必每ơ都做事件源的判断工作,可以其抽象一下交l工L(fng)来完成。jquery中的delegate()Ҏ(gu)实C该功?/p>

语法是这L(fng)$(selector).delegate(childSelector,event,data,function)Q例如:(x)


$("div").delegate("button","click",function(){
  $(
"p").slideToggle();
});
参数说明Q引自w3schoolQ?/code>
参数描述
childSelector 必需。规定要附加事g处理E序的一个或多个子元素?/td>
event

必需。规定附加到元素的一个或多个事g。由I格分隔多个事g倹{必L有效的事件?/p>

data 可选。规定传递到函数的额外数据?/td>
function 必需。规定当事g发生时运行的函数?/td>

 

Tips:事g委托q有一个好处就是,即在事件绑定之后动态添加的元素上触发的事g同样可以监听到哦Q这样就不用在每ơ动态加入元素到面后都为其l定事g?/span>

原文Q?div>http://www.cnblogs.com/gewei/archive/2013/03/29/2988180.html



]]>
վ֩ģ壺 ֶ| | ̨| | | | ɽ| | ̶| ʯ¥| | | Ͳ| | | ʤ| | ֹ| ݳ| | ͤ| Դ| | | Ȫ| ̶| | | | ٽ| ȫ| | н| Ǭ| ũ| | ɽ| | ƺ| | |