我一直认为,出于性能原因,我们不应该反复接触 DOM,而应该使用documentFragment
追加多个元素,然后将片段追加到文档中一次,而不是只是将新元素一个接一个地重复追加到 DOM 中。
我一直在尝试使用 Chrome 的开发工具来分析这两种方法,使用这个测试页面:
<button id="addRows">Add rows</button>
<table id="myTable"></table>
测试 1 使用此代码将 50000 个新行追加到表中:
let addRows = document.getElementById('addRows');
addRows.addEventListener('click', function () {
for (let x = 0; x < 50000; x += 1) {
let table = document.getElementById('myTable'),
row = document.createElement('tr'),
cell = document.createElement('td'),
cell1 = cell.cloneNode(),
cell2 = cell.cloneNode(),
cell3 = cell.cloneNode();
cell1.textContent = 'A';
cell2.textContent = 'B';
cell3.textContent = 'C';
row.appendChild(cell1);
row.appendChild(cell2);
row.appendChild(cell3);
table.appendChild(row);
}
});
在 Chrome 的时间轴工具中录制时单击该按钮会产生以下输出:
测试 2 使用以下代码:
let addRows = document.getElementById('addRows');
addRows.addEventListener('click', function () {
let table = document.getElementById('myTable'),
cell = document.createElement('td'),
docFragment = document.createDocumentFragment();
for (let x = 0; x < 50000; x += 1) {
let row = document.createElement('tr'),
cell1 = cell.cloneNode(),
cell2 = cell.cloneNode(),
cell3 = cell.cloneNode();
cell1.textContent = 'A';
cell2.textContent = 'B';
cell3.textContent = 'C';
row.appendChild(cell1);
row.appendChild(cell2);
row.appendChild(cell3);
docFragment.appendChild(row);
}
table.appendChild(docFragment);
});
它的性能概况如下:
第二个据说比第一个更快的替代方案实际上需要更长的时间来运行!我已经多次运行这些测试,有时第二种方法稍快一些,有时,如这些图像所示,第二种方法稍慢一些,但两种方法之间没有一次出现任何显着差异。
这里发生了什么?浏览器现在已经优化得这么好了,以至于不再有什么区别了吗?我是否错误地使用了分析工具?
我使用的是 Windows 10,Chrome 57.0.2987.133