前端程式越搞越複雜,接踵而至的問題越來越多,雖然瀏覽器的效能不斷地提昇,但是只要IE6沒被淘汰的一天,網頁程式設計師永遠要替IE6補洞,Memory Leak是一個非常難搞得議題。關於微軟的官方說法可以參考Understanding and Solving Internet Explorer Leak Patterns,裡頭有詳細說明IE6會如何發生memory leak的情況。發生memory leak的徵狀就是:記憶體不斷飆上去,就算reload頁面,記憶體也不會被釋放,除非關掉瀏覽器。
在此不介紹為何為引發memory leak,因為我覺得這是瀏覽器應該要處理的問題,要拿出來講只是因為IE6沒辦法處理好罷了,雖然其他瀏覽器也並不是沒有這個問題,但是至少問題都沒有這麼嚴重,因此只需要針對IE6來處理即可。以下是我整理出幾種比較好的處理方式:
function purge(d) {
var a = d.attributes, i, l, n;
if (a) {
l = a.length;
for (i = 0; i < l; i += 1) {
n = a[i].name;
if (typeof d[n] === 'function') {
d[n] = null;
}
}
}
a = d.childNodes;
if (a) {
l = a.length;
for (i = 0; i < l; i += 1) {
purge(d.childNodes[i]);
}
}
}
window.onunload = function(){
purge(document.body);
}
var EventCache = function(){
var listEvents = [];</p>
<p> return {
listEvents : listEvents,</p>
<p> add : function(node, sEventName, fHandler, bCapture){
listEvents.push(arguments);
},</p>
<p> flush : function(){
var i, item;
for(i = listEvents.length - 1; i >= 0; i = i - 1){
item = listEvents[i];</p>
<p> if(item[0].removeEventListener){
item[0].removeEventListener(item[1], item[2], item[3]);
};</p>
<p> /* From this point on we need the event names to be prefixed with 'on" */
if(item[1].substring(0, 2) != "on"){
item[1] = "on" + item[1];
};</p>
<p> if(item[0].detachEvent){
item[0].detachEvent(item[1], item[2]);
};</p>
<p> item[0][item[1]] = null;
};
}
};
}();
function createButton() {
var obj = document.createElement("button");
obj.innerHTML = "click me";
obj.onclick = function() {
//handle onclick
}
obj.onmouseover = function() {
//handle onmouseover
}</p>
<p> //this helps to fix the memory leak issue
try {
return obj;</p>
<p> } finally {
obj = null;
}
}
YAHOO.util.Dom.setInnerHTML = function (el, html) {
el = YAHOO.util.Dom.get(el);
if (!el || typeof html !== 'string') {
return null;
}</p>
<p> // Break circular references.
(function (o) {</p>
<p> var a = o.attributes, i, l, n, c;
if (a) {
l = a.length;
for (i = 0; i < l; i += 1) {
n = a[i].name;
if (typeof o[n] === 'function') {
o[n] = null;
}
}
}</p>
<p> a = o.childNodes;</p>
<p> if (a) {
l = a.length;
for (i = 0; i < l; i += 1) {
c = o.childNodes[i];</p>
<p> // Purge child nodes.
arguments.callee(c);</p>
<p> // Removes all listeners attached to the element via YUI's addListener.
YAHOO.util.Event.purgeElement(c);
}
}</p>
<p> })(el);</p>
<p> // Remove scripts from HTML string, and set innerHTML property
el.innerHTML = html.replace(/<script[^>]*>[\S\s]*?<\/script[^>]*>/ig, "");</p>
<p> // Return a reference to the first child
return el.firstChild;
};
大概是這樣了,memory leak實在是個很惱人的議題,不過有責任感的前端工程是還是要將之視為己任的,畢竟項目越做越大,然而記憶體越吃越兇,這是很可怕的一件事。

Categories
Tag Cloud
Blog RSS
Comments RSS
Last 50 Posts
Back
Void « Default
Life
Earth
Wind
Water
Fire
Light 