Goo*_*ose 2 javascript internet-explorer dom appendchild
我有一个网页,它通过 ajax 调用加载数据,然后填充“表”。它实际上使用一个“div”元素作为行,并使用更多“div”元素作为单元格。出于测试目的,我没有对这些 div 应用任何样式或类,它们只是:<div><div>cell1</div><div>cell2</div></div>
。在测试期间,我加载 2000 行,每行 5 列。
我尝试过使用与这些类似的三种不同方法
function test(method) {
var totalRows = 2000;
var totalCols = 6;
var rows = [];
var r, c, row, cell;
for (r = 0; r < totalRows; r++) {
row = [];
rows.push(row);
for (c = 0; c < totalCols; c++) {
row.push(r + ':' + c + ' Just some text');
}
}
var container = document.getElementById('container');
var output = document.getElementById('output');
var div = document.createElement('div');
container.innerHTML = '';
var start = new Date().getTime();
switch (method) {
case 1:
for (r = 0; r < totalRows; r++) {
row = div.cloneNode(false);
container.appendChild(row);
for (c = 0; c < totalCols; c++) {
cell = div.cloneNode(false);
cell.appendChild(document.createTextNode(rows[r][c]));
row.appendChild(cell);
}
}
break;
case 2:
var outer = document.createElement('div');
var frag = document.createDocumentFragment();
for (r = 0; r < totalRows; r++) {
row = div.cloneNode(false);
frag.appendChild(row);
for (c = 0; c < totalCols; c++) {
cell = div.cloneNode(false);
cell.appendChild(document.createTextNode(rows[r][c]));
row.appendChild(cell);
}
}
container.appendChild(frag);
break;
case 3:
var els = [];
for (r = 0; r < totalRows; r++) {
els.push('<div>');
for (c = 0; c < totalCols; c++) {
els.push('<div>');
els.push(rows[r][c]);
els.push('</div>');
}
els.push('</div>');
}
// ignore string creation
start = new Date().getTime();
container.innerHTML = els.join('');
break;
}
var end = new Date().getTime();
output.innerHTML = 'time: ' + (end - start);
}
Run Code Online (Sandbox Code Playgroud)
<input type="button" value="Method 1 (Direct)" onclick="test(1)"><br>
<input type="button" value="Method 2 (Fragment)" onclick="test(2)"><br>
<input type="button" value="Method 3 (innerHTML)" onclick="test(3)"><br>
<div id="output"></div>
<div id="container">
</div>
Run Code Online (Sandbox Code Playgroud)
方法1)创建元素并直接插入到DOM中;
方法 2) 创建一个文档片段并将其附加到其中。最后将片段插入到 DOM 中;
方法3)创建文本HTML表示并设置innerHTML。
在前两种方法中,我克隆元素而不是创建它们。
我在这部分使用纯 JavaScript。这些示例使用 Firefox 运行得非常快,全部不到 40 毫秒。使用 IE 11,前两种方法的运行时间约为 2000 毫秒,而第三种方法的运行时间为 150 毫秒。这对于我的需求来说是可以接受的。
当我在实际的 Web 应用程序中尝试这些方法时,问题就出现了。“表”嵌套在一个更加复杂的结构中。不幸的是,它对我来说太复杂了,无法提供一个有效的例子。表本身保留完全相同的结构。使用 Firefox 时,该表将在大约 1 秒内显示(从服务器获取数据后)。这是可以接受的。然而,IE 需要 20 秒以上,而且我使用三种方法中的哪一种几乎没有什么区别。
使用方法 2(首先附加到文档片段),我可以在探查器中看到,准备片段需要不到一秒的时间,但将片段附加到 DOM 需要 23 秒。探查器显示大量“DOM 事件 (DOMNodeInserted)”事件,后跟“垃圾收集”事件。其中大约有 40 个。注意:此配置文件来自应用程序而不是代码片段。
探查器将 GC 条目标记为 JavaScript 垃圾收集(而不是某些内部 IE 内容)。我的问题是:
为什么它会触发 DOMNodeInserted 事件?
GC 的工作原理是什么(此时没有任何变量超出范围)?
为什么分析器每第二个或第三个事件显示 3 秒间隙(各个位的时间不相加)?
我的代码可以改进吗?
我尝试了所有我能想到的优化,包括:在构建时将样式显示设置为无;克隆节点而不是创建节点;并在循环之外声明变量。据我所知,我没有任何事件侦听器附加到 DOM 的这一部分。
归档时间: |
|
查看次数: |
2803 次 |
最近记录: |