元素事件Javascript执行效率小结

查了好多资料,发现还是不全,干脆自己整理吧,至少保证在我的做法正确的,以免误导读者,也是给自己做个记载吧!

    Javascript是一门非常灵活的语言,我们可以随心所欲的誊写各种风格的代码,不同风格的代码也必定也会导致执行效率的差异,开发过程中零零散散地接触到许多进步代码性能的方法,整理一下平常比拟常见并且轻易规避的问题

    

Javascript自身执行效率

    Javascript中的作用域链、闭包、原型继承、eval等特性,在提供各种奇异功能的同时也带来了各种效率问题,用之不慎就会导致执行效率低下。

    

1、全局导入

    我们在编码过程中多多少少会应用到一些全局变量(window,document,自定义全局变量等等),懂得javascript作用域链的人都知道,在局部作用域中拜访全局变量需要一层一层遍历全部作用域链直至顶级作用域,而局部变量的拜访效率则会更快更高,因此在局部作用域中高频率应用一些全局对象时可以将其导入到局部作用域中,例如:

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

2、eval以及类eval问题

    我们都知道eval可以将一段字符串当做js代码来执行处理,据说应用eval执行的代码比不应用eval的代码慢100倍以上(详细效率我没有测试,有兴致同学可以测试一下)

    

    JavaScript 代码在执行前会停止类似“预编译”的操作:首先会创立一个当前执行环境下的活动对象,并将那些用 var 声名的变量设置为活动对象的属性,但是此时这些变量的赋值都是 undefined,并将那些以 function 定义的函数也添加为活动对象的属性,而且它们的值正是函数的定义。但是,如果你应用了“eval”,则“eval”中的代码(实际上为字符串)没法事后识别其上下文,没法被提前剖析和优化,即没法停止预编译的操作。所以,其性能也会大幅度下降

    

    其实当初大家一般都很少会用eval了,这里我想说的是两个类eval的场景(new Function{},setTimeout,setInterver)

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

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

(new Function("alert(1)"))();
上述几种类型代码执行效率都会比拟低,因此提议直接传入匿名方法、或者方法的引用给setTimeout方法

    

3、闭包结束后释放掉不再被引用的变量

var f = (function(){
    var a = {name:"var3"};
    var b = ["var1","var2"];
    var c = document.getElementByTagName("li");
    //****其它变量
    //***一些运算
    var res = function(){
        alert(a.name);
    }
    return res;
})()
上述代码中变量f的返回值是由一个立即执行函数构成的闭包中返回的方法res,该变量保留了对于这个闭包中所有变量(a,b,c等)的引用,因此这两个变量会始终驻留在内存空间中,尤其是对于dom元素的引用对内存的消费会很大,而我们在res中只应用到了a变量的值,因此,在闭包返回前我们可以将其它变量释放
var f = (function(){
    var a = {name:"var3"};
    var b = ["var1","var2"];
    var c = document.getElementByTagName("li");
    //****其它变量
    //***一些运算
    //闭包返回前释放掉不再应用的变量
    b = c = null;
    var res = function(){
        alert(a.name);
        }
    return res;
})()

Js操作dom的效率

    在web开发过程中,前端执行效率的瓶颈往往都是在dom操作上面,dom操作是一件很耗性能的事件,如何才能在dom操作过程中尽量节约性能呢?

    

1、减少reflow

    

什么是reflow?

    

    当 DOM 元素的属性产生变更 (如 color) 时, 浏览器会通知 render 从新描写响应的元素, 此过程称为 repaint。

    如果该次变更涉及元素布局 (如 width), 浏览器则摈弃原有属性, 从新盘算并把结果传递给 render 以从新描写页面元素, 此过程称为 reflow。

    每日一道理
生活中受伤难免,失败跌倒并不可怕,可怕的是因此而一蹶不振,失去了对人生的追求与远大的理想。没有一个人的前进道路是平平稳稳的,就算是河中穿梭航行的船只也难免颠簸,生活中所遇上的坎坷磨难不是偶尔给予的为难,而是必定所经受的磨练。

    

    

减少reflow的方法

    

  1. 先将元素从document中删除,完成修改后再把元素放回本来的位置(当对某元素及其子元素停止大量reflow操作时,1,2两种方法效果才会比拟显著)

  2. 将元素的display设置为”none”,完成修改后再把display修改为本来的值

  3. 修改多个样式属性时定义class类取代多次修改style属性(for certain同学推荐)
  4. 大量添加元素到页面时应用documentFragment

    例如

for(var i=0;i<100:i++){
    var child = docuemnt.createElement("li");
    child.innerHtml = "child";
    document.getElementById("parent").appendChild(child);
}
上述代码会多次操作dom,效率比拟低,可以改为上面的形式 创立documentFragment,将所有元素参加到docuemntFragment不会转变dom结构,最后将其添加到页面,只停止了一次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状态信息

    当代码中需要多次拜访元素的状态信息,在状态不变的情况下我们可以将其暂存到变量中,这样可以防止多次拜访dom带来内存的开销,典型的例子就是:

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

3、缩小选择器的查找范围

    查找dom元素时尽量防止大面积遍历页面元素,尽量应用精准选择器,或者指定上下文以缩小查找范围,以jquery为例

    

  • 少用模糊匹配的选择器:例如$("[name*='_fix']"),多用诸如id以及逐渐缩小范围的复合选择器$("li.active")
  • 指定上下文:例如$("#parent .class")$(".class",$el)

    

4、应用事件委托

    应用场景:一个有大量记载的列表,每条记载都需要绑定点击事件,在鼠标点击后实现某些功能,我们平日的做法是给每条记载都绑定监听事件,这种做法会导致页面会有大量的事件监听器,效率比拟低下。

    基本原理:我们都知道dom规范中事件是会冒泡的,也就是说在不主动阻挠事件冒泡的情况下任何一个元素的事件都会按照dom树的结构逐级冒泡至顶端。而event对象中也提供了event.target(IE下是srcElement)指向事件源,因此我们即使在父级元素上监听该事件也可以找到触发该事件的最原始的元素,这就是委托的基本原理。废话不多说,上示例

$("ul li").bind("click",function(){
    alert($(this).attr("data"));
})
上述写法其实是给所有的li元素都绑定了click事件来监听鼠标点击每一个元素的事件,这样页面上会有大量的事件监听器。

    根据上面介绍的监听事件的原理我们来改写一下

$("ul").bind("click",function(e){
    if(e.target.nodeName.toLowerCase() ==="li"){
        alert($(e.target).attr("data"));
    }
})
这样一来,我们就可以只添加一个事件监听器去捕获所有li上触发的事件,并做出响应的操作。

    当然,我们不必每次都做事件源的判断任务,可以将其抽象一下交给工具类来完成。jquery中的delegate()方法就实现了该功能

    语法是这样的$(selector).delegate(childSelector,event,data,function),例如:

$("div").delegate("button","click",function(){
  $("p").slideToggle();
});

    参数说明(引自w3school)

    

    

参数描述
childSelector必须。划定要附加事件处理程序的一个或多个子元素。
event

必须。划定附加到元素的一个或多个事件。由空格分隔多个事件值。必须是有效的事件。

data可选。划定传递到函数的额定数据。
function必须。划定当事件产生时运行的函数。

 

    Tips:事件委托还有一个利益就是,即使在事件绑定之后动态添加的元素上触发的事件同样可以监听到哦,这样就不用在每次动态参加元素到页面后都为其绑定事件了

    临时先总结到这

文章结束给大家分享下程序员的一些笑话语录: 看新闻说中国输入法全球第一!领先了又如何?西方文字根本不需要输入法。一点可比性都没有。


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
毕设新项目-基于Java开发的智慧养老院信息管理系统源码+数据库(含vue前端源码).zip 【备注】 1、该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的,请放心下载使用!有问题请及时沟通交流。 2、适用人群:计算机相关专业(如计科、信息安全、数据科学与大数据技术、人工智能、通信、物联网、自动化、电子信息等)在校学生、专业老师或者企业员工下载使用。 3、用途:项目具有较高的学习借鉴价值,不仅适用于小白学习入门进阶。也可作为毕设项目、课程设计、大作业、初期项目立项演示等。 4、如果基础还行,或热爱钻研,亦可在此项目代码基础上进行修改添加,实现其他不同功能。 欢迎下载!欢迎交流学习!不清楚的可以私信问我! 毕设新项目-基于Java开发的智慧养老院信息管理系统源码+数据库(含vue前端源码).zip毕设新项目-基于Java开发的智慧养老院信息管理系统源码+数据库(含vue前端源码).zip毕设新项目-基于Java开发的智慧养老院信息管理系统源码+数据库(含vue前端源码).zip毕设新项目-基于Java开发的智慧养老院信息管理系统源码+数据库(含vue前端源码).zip毕设新项目-基于Java开发的智慧养老院信息管理系统源码+数据库(含vue前端源码).zip毕设新项目-基于Java开发的智慧养老院信息管理系统源码+数据库(含vue前端源码).zip毕设新项目-基于Java开发的智慧养老院信息管理系统源码+数据库(含vue前端源码).zip毕设新项目-基于Java开发的智慧养老院信息管理系统源码+数据库(含vue前端源码).zip毕设新项目-基于Java开发的智慧养老院信息管理系统源码+数据库(含vue前端源码).zip
综合小区管理系统管理系统按照操作主体分为管理员和用户。管理员的功能包括报修管理、车位管理、车位分配管理、出入管理、字典管理、房屋管理、物业费缴纳管理、公告管理、物业人员投诉管理、我的私信管理、物业人员管理、用户管理、管理员管理。用户的功能包括管理部门以及部门岗位信息,管理招聘信息,培训信息,薪资信息等。该系统采用了Mysql数据库,Java语言,Spring Boot框架等技术进行编程实现。 综合小区管理系统管理系统可以提高综合小区管理系统信息管理问题的解决效率,优化综合小区管理系统信息处理流程,保证综合小区管理系统信息数据的安全,它是一个非常可靠,非常安全的应用程序。 管理员权限操作的功能包括管理公告,管理综合小区管理系统信息,包括出入管理,报修管理,报修管理,物业费缴纳等,可以管理操作员。 出入管理界面,管理员在出入管理界面中可以对界面中显示,可以对招聘信息的招聘状态进行查看,可以添加新的招聘信息等。报修管理界面,管理员在报修管理界面中查看奖罚种类信息,奖罚描述信息,新增奖惩信息等。车位管理界面,管理员在车位管理界面中新增。公告管理界面,管理员在公告管理界面查看公告的工作状态,可以对公告的数据进行导出,可以添加新公告的信息,可以编辑公告信息,删除公告信息。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值