限制 DOM 更新

在瀏覽器環境中執行時,JavaScript 中常見的錯誤是更頻繁地更新 DOM。

這裡的問題是 DOM 介面中的每次更新都會導致瀏覽器重新呈現螢幕。如果更新更改了頁面中元素的佈局,則需要重新計算整個頁面佈局,即使在最簡單的情況下,這也是非常高效能的。重新繪製頁面的過程稱為迴流,並可能導致瀏覽器執行緩慢甚至停止響應。

使用以下向列表中新增專案的示例說明了過於頻繁地更新文件的結果。

請考慮以下包含 <ul> 元素的文件:

<!DOCTYPE html>
<html>
    <body>
        <ul id="list"></ul>
    </body>
</html>

我們將 5000 項新增到迴圈 5000 次的列表中(你可以在功能強大的計算機上嘗試使用更大的數字來增加效果)。

var list = document.getElementById("list");
for(var i = 1; i <= 5000; i++) {             
    list.innerHTML += `<li>item ${i}</li>`;  // update 5000 times
}

在這種情況下,可以通過在一個 DOM 更新中批量處理所有 5000 個更改來提高效能。

var list = document.getElementById("list");
var html = "";
for(var i = 1; i <= 5000; i++) {
    html += `<li>item ${i}</li>`;
}
list.innerHTML = html;     // update once

函式 document.createDocumentFragment() 可以用作迴圈建立的 HTML 的輕量級容器。此方法比修改容器元素的 innerHTML 屬性稍快(如下所示)。

var list = document.getElementById("list");
var fragment = document.createDocumentFragment();
for(var i = 1; i <= 5000; i++) {
    li = document.createElement("li");
    li.innerHTML = "item " + i;
    fragment.appendChild(li);
    i++;
}
list.appendChild(fragment);