事件_内存和性能-读书笔记五

本文深入探讨了在JavaScript中处理事件时如何优化页面性能,通过采用事件委托减少事件处理程序的数量,并在不使用事件处理程序时及时移除它们,以减轻内存负担和提升页面响应速度。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

        在javascript中,添加到页面上的事件处理程序数量关系到页面的整体运行性能。导致这一问题的原因是多方面的。首先,每个函数都是对象,都会占有内存,内存中的对象越多,性能就越差。其次,事先指定所有事件处理程序而导致DOM访问过多,会延迟整个页面的交互就绪时间。

事件委托

        对“事件处理程序过多”问题的解决方案就是事件委托。事件委托利用了事件冒泡,只指定一个事件处理程序,就可以管理某一类型的所有事件。HTML代码

	<ul id="ulId" >
		<li id="id1"> go somewhere </li>
		<li id="id2"> do something </li>
		<li id="id2"> say hello </li>
	</ul>

按照传统的做法,很可能像下面这样为他们添加事件处理程序:


var item1 = document.getElementById("id1");
var item2 = document.getElementById("id2");
var item3 = document.getElementById("id3");

EventUtil.addHandler(item1,"click",function(event) {
	location.href = "http://www.baidu.com";
})

EventUtil.addHandler(item2,"click",function(event) {
	//do something
	document.title = change document title.'';
})

EventUtil.addHandler(item3,"click",function(event) {
	alert('hi, jack');
})


         如果在一个复杂的web应用程序中,对所有的可单击的元素都采取这种方式,那么结果就会有数不清的代码用于添加事件处理程序。此时,可以利用事件委托类解决此问题。使用事件委托,只需在DOM树中尽量最高层次上添加一个事件处理程序。代码如下:

var div = document.getElementById('ulId');

EventUtil.addHandler(div,'click',function(event){
	event = EventUtil.getEvent(event);
	
	var target = EventUtil.getTarget(event);
	
	switch(target.id) {
		case "id1" :
			location.href = "http://www.baidu.com";
			break;
		case "id2" :
			document.title = change document title.'';
			break;
		case "id3"
			alert('hi, jack');
			break;
	}
})

        由于所有的li元素都是ul元素的子元素,而且他们的事件冒泡,所以单击事件最终都会被这个函数处理。
这种做法与传统的做法相比有如下优点:

    a. document对象可以很快访问到,而且可以在页面生命周期的任何时间点上为它添加事件处理程序。

    b.在页面中设置处理事件程序事件更少。

    c.整个页面占有的内存空间更少。

比较适合采用事件委托的事件包括click,mousedown,keydown,mouseup,keyup,keypress。

移除事件处理程序

        每当给事件处理程序指定给元素时,运行中的浏览器代码与支持页面交互的javascript代码之间就会建立一个连接。这种连接越多,页面执行速度就会越慢。在不需要的时候移除事件处理程序,也是一种解决方案。内存中留有那些过时不用的“空事件处理程序”,也是造成Web应用程序内存与性能的问题的主要原因。

        在两种情况下,可能会造成上述问题。第一种情况就是从文档中移除带有事件处理程序的元素时。这可能是通过纯粹的DOM操作,例如使用removeChild()和replaceChild()方法,更多的是使用innerHTML替换页面中的某一部分时候,如果带有事件处理程序的元素被替换掉,那么原来添加到元素中的事件处理程序极有可能无法被当做垃圾回收。如下示例:

 	<div id="id1">
 		<input type="button" value="click" id="button"/>
 	</div>
 
 	<script type="text/javascript">
 		var btn = document.getElementById("button");
 		btn.onclick = function() {
 			//do something	
 			document.getElementById("id1").innerHTML("PROCESS ...") //注意此处
 		};
 	</script>

问题在于,当按钮从页面被移除时,它还带着一个事件处理程序呢。虽然按钮被移除了,但是事件处理程序和按钮还保持着引用关系。很有可能这种关系被保存在内存中。因此如果要移除一个元素,需要把元素上的所有事件处理程序同样移除走。


  <script type="text/javascript">
 		var btn = document.getElementById("button");
 		btn.onclick = function() {
 			//do something
 			btn.onclick = null;//移除事件处理程序	
 			document.getElementById("id1").innerHTML("PROCESS ...") //注意此处
 		};
 </script>


 

        另外一种情况就是卸载页面的时候。IE是在这种情况下问题最多的浏览器,尽管其他浏览器或多或少也有类似的问题。如果在页面被卸载之前没有清理干净事件处理程序,那他们就会滞留在内存中,每次加载完之后再卸载页面,内存中滞留的对象就会越来越多,因为事件处理程序占有的内存并没有释放。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值