JScript的内存泄漏之后续篇
JScript Memory Leaks in Microsoft IE solution 2
正像我上篇文章翻译的一样,Microsoft Internet Explorer 在DOM对象增加事件句柄后会带来内存泄漏的问题。上篇文章也给出了解决方案,但是如果在开发者未知该何时调用这个净化程序时,一般开发者会加入类似的代码:
if ( Nebula.isIE ) { window.attachEvent("onunload", function () { Nebula.clearEvent ( document.body ); }); }
这里的Nebula.clearEvent就是上述的净化程序,它在你离开页面或刷新页面时触发,这很重要。比如你正在浏览Gmail,但不知道什么原因导致你必须刷新gmail,这时如果不调用净化程序内存仍然是得不到释放。
是的,你也许也发现了我们传进去的是document.body,这意味着要对整个html文档进行递归地循环地“净化”,效率是很低的。于是我改进了这个方法。
/** * The basic global namespace * @constructor */ window.Nebula = { /** * get the Nebula lib 's version * @type {string} */ version: "1.1.0.0", /** * Boolean flag that navigator whether it is MCST IE * @type boolean */ isIE: !!window.ActiveXObject, /** * Boolean flag that navigator whether it is Apple Safari * @type boolean */ isSafari: navigator.userAgent.toLowerCase().indexOf("safari") > -1 , /** * Boolean flag that navigator whether it is Opera * @type boolean */ isOpera: navigator.userAgent.toLowerCase().indexOf("opera") > -1 , /** * event names */ _eventList: ["onbeforecut", "onblur", "onclick", "oncontextmenu", "oncut", "ondblclick", "ondeactivate", "ondragenter", "ondragleave", "ondragover", "ondrop", "onfocus", "onfocusin", "onfocusout", "onhelp", "onkeydown", "onkeypress", "onkeyup", "onmousedown", "onmouseenter", "onmouseleave", "onmousemove", "onmouseout", "onmouseover", "onmouseup", "onmousewheel", "onmove", "onmoveend", "onmovestart", "onpaste", "onreadystatechange", "onresize", "onresizeend", "onresizestart", "onselectstart" ], /** * clear html element 's event handle, fix ie MEMORY LEAKS bug * @param d , the element of cleared */ clearEvent: function (d) { var a, i, l, n; if (!d || !this.isIE) { return; } a = this._eventList; try{ if (a) { l = a.length; for (i = 0; i < l; i += 1) { n = a[i]; if (typeof d[n] === "function") { d[n] = null; } } } a = d.childNodes; if (a) { l = a.length; for (i = 0; i < l; i += 1) { this.clearEvent(d.childNodes[i]); } } }catch(ex){ //alert(ex.message); } } }; if ( Nebula.isIE ) { window.attachEvent("onunload", function () { Nebula.clearEvent ( document.body ); }); }
我把DOM元素可能用到event列出来,然后去再去循环这些event,而不是DOM的所有属性。这样好处将会提高效率,减少数万次计算。
没有评论:
发表评论