我有一個網頁,通過ajax調用加載數據,然後填充一個「表」。它實際上使用'div'元素作爲一行,更多'div'元素作爲單元格。爲了測試目的,我沒有將這些div應用於任何樣式或類,它們僅僅是:<div><div>cell1</div><div>cell2</div></div>
。在測試過程中,我加載了2000行,每行5列。互聯網資源管理器11非常緩慢追加元素到DOM
我已經採用類似於這些
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++) {
\t \t 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);
}
<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>
方法1)創建的元素和直接插入到DOM三種不同方法試圖;
方法2)創建一個文檔片段並追加到該文件中。在最後插入片段到DOM;
方法3)創建一個文本HTML表示並設置innerHTML。
在前兩種方法中,我是克隆元素而不是創建它們。
我對這部分使用的是純JavaScript。這些示例使用Firefox非常快速地運行,全部在40毫秒之內。使用IE 11,前兩種方法在大約2000毫秒內運行,而第三種方法在150毫秒內運行。這對我的需求是可以接受的。
當我在實際的Web應用程序中嘗試這些方法時出現問題。 「表」嵌套在一個更復雜的結構中。不幸的是,提供一個工作示例對我來說太複雜了。表本身保留完全相同的結構。使用Firefox時,表格會在大約1秒鐘內顯示(從服務器獲取數據之後)。這是可以接受的。然而IE瀏覽器需要花費20多秒的時間,這對我使用的三種方法中的哪一種沒有什麼影響。
使用方法2(首先追加到一個文檔片段)我可以在剖析器中看到它在一秒之內準備片段,但在23秒後將片段追加到DOM。分析器顯示大量的「DOM事件(DOMNodeInserted)」事件,後面跟着「垃圾收集」。其中可能有40個。注意:此配置文件來自應用程序而不是代碼片段。
分析器將GC條目標記爲JavaScript垃圾回收(而不是一些內部的IE東西)。我的問題是:
它爲什麼會觸發DOMNodeInserted事件?
什麼是GC工作(此時沒有變量超出範圍)?
爲什麼事件探查器每隔第二或第三個事件顯示3個第二個間隔(各個位的時間不相加)?
我的代碼可以改進嗎?
我已經嘗試過所有我能想到的優化,包括:在創建時將樣式顯示設置爲無;克隆節點而不是創建它們;並在循環之外聲明變量。據我可以推斷,我沒有任何事件監聽器附加到這部分的DOM。
在此處發佈您的代碼,而不僅僅是在遠程站點。您可以使用[Stack Snippets](https://stackoverflow.blog/2014/09/introducing-runnable-javascript-css-and-html-code-snippets/)使其可執行。 – Barmar