页面海量数据优化加载

要求:将10W条数据一次渲染到页面上?

分析:
·数据量过大,出现卡顿感的主要原因是,在每次循环中,都会修改 DOM 结构,并且由于数据量大,导致循环执行时间过长,浏览器的渲染帧率过低。
·从 减少 DOM 操作次数 和 缩短循环时间 两个方面减少主线程阻塞的时间.
·通过 DocumentFragment 的使用,减少 DOM 操作次数,降低回流对性能的影响;
·在缩短循环时间方面,我们可以通过 分治 的思想,将 100000 个 li 分批插入到页面中,并且我们通过 requestAniminationFrame 在页面重绘前插入新节点。

DocumentFragment节点不属于文档树,继承的parentNode属性总是null。它有一个很实用的特点,当请求把一个DocumentFragment节点插入文档树时,插入的不是DocumentFragment自身,而是它的所有子孙节点。这个特性使得DocumentFragment成了占位符,暂时存放那些一次插入文档的节点。

HTML:

<ul id="oUl"></ul>

JS:

(function () {
    const oUl = document.getElementById("oUl");

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

    const total = 10000;    //插入数据的总数
    const size = 4;         //每次批量插入的节点数,个数越多,页面越卡顿
    const count = total/size;   //批处理的次数
    let num = 0;            //完成处理的次数

    //往列表插入 10w 个 li ,每个列表项的文本内容可自行定义
    function appendItems() {
        //使用 DocumentFragment 减少 DOM 操作次数,对已有元素不进行回流
        const fragment = document.createDocumentFragment('li');

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

        //每次批处理只修改一次DOM
        oUl.appendChild(fragment);
        num++;
        doAppendBatch();
    }

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

    doAppendBatch();

    //要求当每个 li 被单击时,通过 alert 显示列表项内的文本内容
    //使用 事件委托 ,利用 JavaScript 的事件机制,实现对海量元素的监听,有效减少事件注册的数量
    oUl.addEventListener("click",function (e) {
        var e = e || window.event;    //兼容IE
        const target = e.target || e.srcElement;
        if(target.nodeName.toUpperCase() === "LI")
            alert(target.innerText);
    })

})();

猜你喜欢

转载自blog.csdn.net/wang_NiFeng/article/details/81749022
今日推荐