Javascript高级编程学习笔记(70)—— 事件(14)内存和性能
由于事件处理程序是现代的web程序交互能力的提供者
所以在日常实践中,我们免不了要向页面中添加大量的事件处理程序(不管是用于用户交互还是用于统计用户数据)
在创建GUI(图形用户界面)的语言(如C#)中,为GUI中的每一个按钮添加一个onclick事件是司空见惯的事,并且这样做并不会有什么问题
但是在JS中情况就截然不同了,因为在web应用中添加到页面上的事件处理程序的数量将直接影响页面的整体运行性能
导致这一问题的原因有以下几点:
- JS中每个函数都是对象,都会占用内存,内存占用越多性能越差
- 由于JS需要事先指定事件处理程序,所以会导致DOM访问次数的增加,随着访问次数的增加会延迟整个页面的交互时间
但是我们可以用一些技巧来改善页面的性能
事件委托
对于页面中事件处理程序过多这一现象的解决方法就是采用事件委托
事件委托可以大幅降低页面中事件处理程序的数量
那么什么是事件委托呢?
事件委托就是利用事件冒泡,给整个页面添加一个事件处理程序就可以管理这一类的事件
以onclick 事件为例
一般情况下我们很有可能为页面上的所有可点击元素都添加他们的事件处理程序
但是这样一来页面上的事件处理程序的数量就可想而知了
但如果我们采用事件委托的方式,如下代码所示:
<ul id = "myLinks"> <li id="1">1</li> <li id="2">2</li> </ul>
对于上述的HTML结构,我们可以用下面的方式为其添加事件处理程序
var list = document.getElementById("myLinks"); list.onlick = function(event){ var target = event.target; switch(target.id){ case "1": alert("1"); break; case "2": alert("2"); break; } }
这样一来一个事件处理程序就可以完成原本两个或者更多事件处理程序的工作
如果条件允许的话,我们甚至可以直接为document添加一类的事件处理程序
然后在内部再对其进行细分,完成不同的操作
移除事件处理程序
JS中的垃圾回收机制我们之前提到过
除了对于循环引用可能造成内存泄漏之外
对于事件的处理不当也会造成内存泄漏,甚至更为严重
因为这一类的内存泄漏比循环引用更加不易察觉
由于事件处理程序会占用内存,所以一旦我们从页面中删除了事件处理程序所绑定的元素
而没有对已经绑定的事件处理程序解除引用,这样一来事件处理程序所占用的内存就得不到释放
随着泄漏的内存增加,页面性能自然就会逐渐降低
所以改善页面性能另一个重要的地方就在于要及时地移除事件处理程序
即当我们知道某个元素即将被移的时候,那么我们最好手动地移除事件处理程序
方法如下:
- 将onclick等事件属性设为 null
- 对于addEventListener 添加的事件 我们用对应的 removeEventListener移除即可