2009-04-20 4 views
27

Tôi có một ứng dụng cho phép người dùng xem chi tiết về một trường hợp cụ thể bằng cách đăng lại. Mỗi lần người dùng yêu cầu dữ liệu từ máy chủ tôi kéo xuống đánh dấu sau.Cách xử lý các phần tử DOM trong JavaScript để tránh rò rỉ bộ nhớ

<form name="frmAJAX" method="post" action="Default.aspx?id=123456" id="frmAJAX"> 
<div> 
<input type="hidden" name="__VIEWSTATE" id="__VIEWSTATE" /> 
</div> 
<div> 
<input type="hidden" name="__EVENTVALIDATION" id="__EVENTVALIDATION" /> 
</div> 
<div id="inner"> 
<!-- valid info here --!> 
</div> 
</form> 

Tiếp theo, tôi lấy trên và innerHTML nó vào một phần tử DOM mới như vậy:

success: function(xhtml) { 
     var tr = document.createElement('tr'); 
     var td = document.createElement('td'); 
     var container = document.createElement('div'); 

     obj.parentNode.parentNode.parentNode.insertBefore(tr, obj.parentNode.parentNode.nextSibling); 

     td.appendChild(container); 
     container.innerHTML = xhtml; 
     tr.appendChild(td); 

nhưng sau khi ở trên, tôi sử dụng một số jQuery để loại bỏ các aspnet khó chịu rác

$('form:eq(1)').children().each(
    function() { 
     if ($('form:eq(1)').find('div').filter(function() { return $(this).attr('id') == ''; }).remove()); 
    } 
); 

//Capture the remaining children 
var children = $('form:eq(1)').children(); 

// Remove the form 
$('form:eq(1)').remove(); 

// append the correct child element back to the DOM 
parentObj.append(children); 

Câu hỏi của tôi là như vậy - Khi sử dụng IESieve Tôi nhận thấy không có rò rỉ thực tế nhưng số lượng DOM ngày càng tăng (do đó sử dụng bộ nhớ).

Tôi có thể cải thiện điều gì ở phía máy khách để dọn dẹp đống lộn xộn này? Lưu ý - cả IE7/8 đều hiển thị các kết quả này.

EDIT: Cuối cùng tôi đã làm việc này và quyết định viết một đoạn mã ngắn blog post với mã nguồn hoàn chỉnh.

+0

Bạn thực sự nên chấp nhận một câu trả lời cho câu hỏi này ngay bây giờ .... – Blazemonger

+0

Bạn có thể cập nhật URL để blog post? – Christian

+1

@Christian vừa làm (xin lỗi vì liên kết bị hỏng) –

Trả lời

12

Phần khó khăn là tìm ra nơi tham chiếu vẫn tồn tại đối với các nút vi phạm.

Bạn đang làm điều này một cách khó khăn - bạn đang thêm tất cả đánh dấu vào trang, sau đó xóa nội dung bạn không muốn. Thay vào đó, tôi sẽ làm theo cách này:

var div = document.createElement('div'); 
// (Don't append it to the document.) 

$(div).html(xhtml); 

var stuffToKeep = $(div).find("form:eq(1)> *").filter(
    function() { 
    return $(this).attr('id') !== ''; 
    } 
); 

parentObj.append(stuffToKeep); 

// Then null out the original reference to the DIV to be safe. 
div = null; 

Điều này không được đảm bảo để ngăn chặn sự rò rỉ, nhưng đó là một khởi đầu tốt.

+0

Đây là một bước tiến lớn vì hầu hết các phần tử DOM chỉ treo xung quanh là những phần tử tôi đã xóa và không bao giờ được sử dụng. Cảm ơn bạn! –

2

remove() và ilk của nó chỉ xóa các phần tử khỏi DOM. Chúng vẫn tồn tại trong trí nhớ ở đâu đó.

Đây là sự cố đã biết với AJAX và Web 2.0. Có rất ít bạn có thể làm ngoài việc thiết kế trang web của bạn để đảm bảo rằng đôi khi bạn có một trang làm mới để xóa sạch mọi thứ.

+3

Bạn không thể vứt bỏ chúng theo cách sao cho khi bộ thu gom rác javascript đi xung quanh, những các phần tử được xóa khỏi bộ nhớ? –

+0

Người ta sẽ cho rằng đó là trường hợp, nhưng rõ ràng là không. – Randolpho

+2

Hmm ... sau một số lần đào, bạn có thể thử một số giải pháp được thảo luận trên trang này: http://social.msdn.microsoft.com/Forums/en-US/iewebdevelopment/thread/c76967f0-dcf8-47d0-8984 -8fe1282a94f5 – Randolpho

1

Tôi nghĩ rằng "mức tiêu thụ bộ nhớ luôn tăng" có phần bị hiểu lầm. Nó phải làm với quản lý bộ nhớ bên trong trình duyệt (và cũng trên Windows nói chung) nhiều hơn nó đã làm với mã JS của bạn. Người quản lý bộ nhớ thường tiếp tục phân bổ (hoặc tránh phát hành) cho đến khi họ phải làm như vậy. Trên các hệ thống dựa trên pagefiles và bộ nhớ ánh xạ, phân bổ và giải phóng bộ nhớ là rất tốn thời gian.

Vì vậy, ngay cả khi các nút của bạn được giải phóng khỏi cấu trúc tài liệu thực tế và DOM - hầu như không có cách nào để đo lường nó từ chính Windows trong "thời gian thực".

Hãy thử điều này:

  1. Bắt đầu Taskmanager, chuyển sang xử lý tab và xem bộ nhớ của trình duyệt của bạn

  2. tải trong một tài liệu HTML mà phân bổ 100.000 nút, xem mức tiêu thụ bộ nhớ lớn

  3. Nhấp vào nút trong trang phát hành tất cả các nút. Lưu ý rằng ít xảy ra trong điều khoản của bộ nhớ phát hành.

  4. Bây giờ, hãy thu nhỏ cửa sổ trình duyệt và tối đa hóa lại.Trong 90% của tất cả các trường hợp trình duyệt hiện nay đổ bộ nhớ nếu không sử dụng và bạn sẽ thấy bao nhiêu nó thực sự tiêu thụ.

Bạn có thể có một trình duyệt tiêu thụ khoảng 500 MB RAM (không nêu trên chẳng hạn), nhưng khi bạn giảm thiểu và tối đa hóa nó, nó giải phóng tất cả mọi thứ và đột nhiên nó chỉ sử dụng 50 MB.

6
function discardElement(element) { 
    var garbageBin = document.getElementById('IELeakGarbageBin'); 
    if (!garbageBin) { 
     garbageBin = document.createElement('DIV'); 
     garbageBin.id = 'IELeakGarbageBin'; 
     garbageBin.style.display = 'none'; 
     document.body.appendChild(garbageBin); 
    } 
    // move the element to the garbage bin 
    garbageBin.appendChild(element); 
    garbageBin.innerHTML = ''; 
} 

Source

+0

Tôi biết có hơi muộn trong trò chơi ... –

+2

Ví dụ tuyệt vời về lý do tại sao IE hút ... –

+2

bạn không giải thích lý do tại sao điều này thậm chí còn hoạt động. không có nghĩa lý gì. – vsync