大量dom操作的优化

按照高程上面的解释
1.使用createDocumentFragment
2.使用innerHTML
3.使用事件代理
4.dom渲染使用requestAnimationFrame进行优化

比如一道笔试题:向ul中添加十万个li。

普通方式为:
(function() {
const ulContainer = document.getElementById("ultest");
// 防御性编程
if (!ulContainer) {
return;
}
for (let i = 0; i < 100000; i++) {
const liItem = document.createElement("li");
liItem.innerText = i + 1;
// EventListener 回调函数的 this 默认指向当前节点,若使用箭头函数,得谨慎
liItem.addEventListener("click", function() {
alert(this.innerText);
});
ulContainer.appendChild(liItem);
}
})()

改进之后:

(function() {
const ulContainer = document.getElementById("ultest");

// 防御性编程
if (!ulContainer) {
return;
}

const total = 100000; // 插入数据的总数
const batchSize = 4; // 每次批量插入的节点个数,个数越多,界面越卡顿
const batchCount = total / batchSize; // 批处理的次数
let batchDone = 0; // 已完成的批处理个数

function appendItems() {
// 使用 DocumentFragment 减少 DOM 操作次数,对已有元素不进行回流
const fragment = document.createDocumentFragment();

for (let i = 0; i < batchSize; i++) {
  const liItem = document.createElement("li");
  liItem.innerText = batchDone * batchSize + i + 1;
  fragment.appendChild(liItem);
}

// 每次批处理只修改 1 次 DOM
ulContainer.appendChild(fragment);
batchDone++;
doAppendBatch();

}

function doAppendBatch() {
if (batchDone < batchCount) {
// 在重绘之前,分批插入新节点
window.requestAnimationFrame(appendItems);
}
}

// kickoff
doAppendBatch();

// 使用 事件委托 ,利用 JavaScript 的事件机制,实现对海量元素的监听,有效减少事件注册的数量
ulContainer.addEventListener("click", function(e) {
const target = e.target;

if (target.tagName === "LI") {
  alert(target.innerText);
}

});
})();

针对documentFragment.appendChild,也可以使用
for(let i = 0; i < 10; i++) {
html +=

  • item

  • }
    进行替换。耗时会花在字符串连接上。但是总体性能要比直接操作dom要快。

    你可能感兴趣的:(大量dom操作的优化)