1. 性能消耗

在 JS 中,添加到页面上的事件处理程序数量将直接关系到页面的整体运行性能,导致问题的原因有:

  • 每个函数都是对象,都会占用内存,内存中的对象越多,性能就越差

  • 必须事先执行所有事件处理程序而导致的 DOM 访问次数,会延迟整个页面的交互就绪时间

每当将事件处理程序指定给元素时,运行中的浏览器代码与支持页面交互的 JS 代码之间就会建立连接,这种连接越多,页面执行就越慢。

2. 解决方案

  • 采用事件委托技术,就限制了连接数量,且节省了内存

  • 在不需要的时候移除事件处理程序,同样也能达到相同的效果

第一种主要用于解决事件程序绑定过多的问题。

第二种主要是用于解决内存中那些过时不用的“空事件处理程序”(dangling event handler)。

(1)从文档中移除带有事件处理程序的元素
如果是通过 DOM 操作移除的,就会被清除。如果是使用 innerHTML 替换掉的页面中的一部分,原本带有事件处理程序的元素极有可能无法被当做垃圾回收。

有的浏览器,尤其是 IE,在这种情况下不会做出恰当的处理,很可能会将对元素和事件处理程序的引用都保存在内存中。所以,如果某个元素即将被移除,最好手动移除事件处理程序。

使用事件委托也有助于解决这个问题,如果事件知道要被 innerHTML 替换掉,那么就不直接把事件处理程序添加到该部分的元素上,而是指定给较高层次的元素。

(2)卸载页面的时候
如果页面被卸载之前没有清理干净事件处理程序,那它们会滞留在内存中,每次加载完页面再卸载页面时,内存中滞留的对象数目就会增加。

最好在页面卸载之前,通过 onunload 事件处理程序,移出所有事件处理程序。事件委托技术在这里也表现出它的优势,需要移除的事件处理程序较少,就越容易。

但是这里使用 unload 事件意味着页面不会被缓存在 bfcache 中。