十年专注于品牌网站建设 十年专注于品牌网站建设,低调、有情怀的网络应用服务商!
南昌百恒网络微信公众号 扫一扫关注
小程序
tel-icon全国服务热线:400-680-9298,0791-88117053
扫一扫关注百恒网络微信公众号
扫一扫打开百恒网络微信小程序

百恒网络

南昌百恒网络

关于内存和性能中移除事件处理程序详细介绍

百恒网络 2017-01-12 828

前面我们介绍过关于内存和性能中的事件委托机制及应用,若对事件委托机制感兴趣,请点击《结合实例介绍JS事件委托机制及应用》查阅,关于性能方面是开发过程中时刻需要考虑的问题,例如,内存示放、链接示放等接下我们着重介绍下连接及页面等方面的性能管控。
       每当将事件处理程序指定给元素时,运行中的浏览器代码与支持页面交互的 JavaScript 代码之间就 会建立一个连接。这种连接越多,页面执行起来就越慢。如前所述,可以采用事件委托技术,限制建立 的连接数量。另外,在不需要的时候移除事件处理程序,也是解决这个问题的一种方案。内存中留有那 些过时不用的“空事件处理程序”(dangling event handler),也是造成 Web 应用程序内存与性能问题的 主要原因。 
       在两种情况下,可能会造成上述问题。第一种情况就是从文档中移除带有事件处理程序的元素时。 这可能是通过纯粹的 DOM操作,例如使用 removeChild()和 replaceChild()方法,但更多地是发 生在使用 innerHTML 替换页面中某一部分的时候。如果带有事件处理程序的元素被 innerHTML 删除 了,那么原来添加到元素中的事件处理程序极有可能无法被当作垃圾回收。来看下面的例子。 

<div id="myDiv">
        <input type="button" value="Click Me" id="myBtn">
</div>
 <script type="text/javascript">
        var btn = document.getElementById("myBtn");
        btn.onclick = function(){ 

//先执行某些操作 
        document.getElementById("myDiv").innerHTML = "Processing..."; //麻烦了! }; 
</script> 
       
这里,有一个按钮被包含在<div>元素中。为避免双击,单击这个按钮时就将按钮移除并替换成一 条消息;这是网站设计中非常流行的一种做法。但问题在于,当按钮被从页面中移除时,它还带着一个 事件处理程序呢。在<div>元素上设置 innerHTML 可以把按钮移走,但事件处理程序仍然与按钮保持 着引用关系。有的浏览器(尤其是 IE)在这种情况下不会作出恰当地处理,它们很有可能会将对元素和 对事件处理程序的引用都保存在内存中。如果你知道某个元素即将被移除,那么好手工移除事件处理 程序,如下面的例子所示。 

<div id="myDiv">
        <input type="button" value="Click Me" id="myBtn">
</div> 
<script type="text/javascript">
        var btn = document.getElementById("myBtn"); 
        btn.onclick = function(){ 

        //先执行某些操作 

        btn.onclick = null; //移除事件处理程序 

        document.getElementById("myDiv").innerHTML = "Processing..."; };
</script> 
在此,南昌网站制作公司百恒网络前端开发工师在提示大家在设置<div>的 innerHTML 属性之前,先移除了按钮的事件处理程序。这样就确保了 内存可以被再次利用,而从 DOM中移除按钮也做到了干净利索。 注意,在事件处理程序中删除按钮也能阻止事件冒泡。目标元素在文档中是事件冒泡的前提。       
        采用事件委托也有助于解决这个问题。如果事先知道将来有可能使用innerHTML 替换掉页面中的某一部分,那么就可以不直接把事件处理程序添加到该部分的元素 中。而通过把事件处理程序指定给较高层次的元素,同样能够处理该区域中的事件。 
        导致“空事件处理程序”的另一种情况,就是卸载页面的时候。毫不奇怪,IE8 及更早版本在这种 情况下依然是问题多的浏览器,尽管其他浏览器或多或少也有类似的问题。如果在页面被卸载之前没 有清理干净事件处理程序,那它们就会滞留在内存中。每次加载完页面再卸载页面时(可能是在两个页 面间来回切换,也可以是单击了“刷新”按钮),内存中滞留的对象数目就会增加,因为事件处理程序 占用的内存并没有被释放。 
       一般来说,好的做法是在页面卸载之前,先通过 onunload 事件处理程序移除所有事件处理程序。 在此,南昌网络公司工程师再次提示大家事件委托技术再次表现出它的优势——需要跟踪的事件处理程序越少,移除它们就越容易。对这 种类似撤销的操作,我们可以把它想象成:只要是通过 onload 事件处理程序添加的东西,后都要通 过 onunload 事件处理程序将它们移除。 
       不要忘了,使用 onunload 事件处理程序意味着页面不会被缓存在 bfcache中。 如果你在意这个问题,那么就只能在IE中通过 onunload 来移除事件处理程序了。 
   本文仅限内部技术人员学习交流,不得作于其他商业用途.希望此文对广大技人员有所帮助。原创文章出自:南昌网站建设公司-百恒网络 http://www.jxbh.cn/ 如转载请注明出处!

400-680-9298,0791-88117053
扫一扫关注百恒网络微信公众号
扫一扫打开百恒网络小程序

欢迎您的光顾,我们将竭诚为您服务×

售前咨询 售前咨询
 
售前咨询 售前咨询
 
售前咨询 售前咨询
 
售前咨询 售前咨询
 
售前咨询 售前咨询
 
售后服务 售后服务
 
售后服务 售后服务
 
备案专线 备案专线
 
×