我循环了一个来自ajax响应的响应,响应是一个包含1000个对象的数组,这个响应用于创建一个1000行的html表:
第一种情况:
for (var i in msg.myObjects) {
$('#mytablebody').append('<tr><td>' + msg.myObjects['item1'] + '</td><td>' +
msg.myObjects['item2'] + '</td><td>' + msg.myObjects['item3'] + '</td><td>' +
msg.myObjects['item4'] + '</td><td>' + msg.myObjects['item5'] + '</td><td>' +
msg.myObjects['item6'] + '</td><td>' + msg.myObjects['item7'] + '</td> .... </tr>');
}
结果=&gt;内存泄漏我的RAM转到了2Go,我的浏览器崩溃了
第二种情况:
for (var i in msg.myObjects) {
document.getElementById('mytablebody').innerHTML = document.getElementById('mytablebody').innerHTML + '<tr><td>' +
msg.myObjects['item1'] + '</td><td>' +
msg.myObjects['item2'] + '</td><td>' + msg.myObjects['item3'] + '</td><td>' +
msg.myObjects['item4'] + '</td><td>' + msg.myObjects['item5'] + '</td><td>' +
msg.myObjects['item6'] + '</td><td>' + msg.myObjects['item7'] + '</td> .... </tr>';
}
结果=&gt;内存泄漏我的RAM达到800Mo,我的浏览器崩溃了第二次ajax调用
第三种情况:
var stringResponse = '';
for (var i in msg.myObjects) {
stringResponse += '<tr><td>' + msg.myObjects['item1'] + '</td><td>' +
msg.myObjects['item2'] + '</td><td>' + msg.myObjects['item3'] + '</td><td>' +
msg.myObjects['item4'] + '</td><td>' + msg.myObjects['item5'] + '</td><td>' +
msg.myObjects['item6'] + '</td><td>' + msg.myObjects['item7'] + '</td> .... </tr>';
}
document.getElementById('mytablebody').innerHTML = stringResponse
结果=&gt;没有内存泄漏
好的,直到这里我得出结论,首先,.append()会导致内存泄漏,其次,你不应该在循环中使用DOM元素。但是当我做第四个场景时,我得出结论,第一个结论是错误(不完全正确),第二个结论仍然是正确的。
第4种情况:
var stringResponse = '';
for (var i in msg.myObjects) {
stringResponse += '<tr><td>' + replaceNulls(msg.myObjects['item1']) + '</td><td>' +
msg.myObjects['item2'] + '</td><td>' + msg.myObjects['item3'] + '</td><td>' +
msg.myObjects['item4'] + '</td><td>' + msg.myObjects['item5'] + '</td><td>' +
msg.myObjects['item6'] + '</td><td>' + msg.myObjects['item7'] + '</td> .... </tr>';
}
document.getElementById('mytablebody').innerHTML = stringResponse
function replaceNulls(input) {
return input != null ? input : ''
}
结果=&gt;内存泄漏我的RAM转到了2Go,我的浏览器崩溃了
我的问题是:
当我们调用在循环外发生的函数时,它可能会导致内存泄漏,为什么?
如何避免这种情况(不删除函数或将处理移到循环内)?
答案 0 :(得分:2)
现代Web浏览器的1000个表条目不应该导致任何问题。
在这里,我将10,000个项目添加到没有ram问题的表中。 它之所以快,是因为我在一个独立的DOM元素中构建了列表,然后在完成后附加。
您的问题可能仅限于DOM绘制问题,浏览器必须重新绘制所有更新。
我注意到的另一件事,for (var i in msg.myObjects)
取决于你的msg.myObjects包含的内容,这不是一件好事。如果你可以使用现代JS, for (const i of msg.myObjects)
更好。
var table = document.querySelector("table");
var tbody = document.createElement("tbody");
function addLine (txt) {
var tr = document.createElement("tr");
var td = document.createElement("td");
tr.appendChild(td);
td.innerText = txt;
tbody.appendChild(tr);
}
for (var l = 1; l <= 10000; l += 1) {
addLine("This is Line " + l + ", and some extra text");
}
table.appendChild(tbody);
&#13;
<table>
<thead><tr><th>Test</th></tr></thead>
</table>
&#13;