You don't have javascript enabled. Good luck! :(

欢迎页

Welcome to Ganace's Blog


欢迎您来到Ganace 的个人博客。

在茫茫互联网的海洋里能够遇见,实在是一份不小的幸运。

诚挚地向您问候一声:您好,朋友!

这里是属于Ganace个人的隐秘小空间,记录了工作学习中遇到的知识点与灵感,以及生活中的碎碎念与吐槽突如其来的中二病尬尬的文艺时间锻炼腹肌的时刻惊喜的小发现等等。

想要在自己的平淡无奇的人生长河中留下些什么,

或者只是为了拯救老人家岌岌可危的记忆力,

仅此而已。

来到此地,分享与你。

也期待与您的再次相遇!

Share with Me


有任何的分享或者建议与吐槽,都可以Email我:ganace@foxmail.com

欢迎您的来信!

【Front】如何一次性渲染十万条数据还能保证页面不卡顿requestAnimationFrame

  Apr 22, 2024     Ganace     Front-end-Foundation

Front

前端优化方案如何一次性渲染十万条数据还能保证页面不卡顿的总结笔记。


requestAnimationFrame 与 fragment(时间分片)结合

window.requestAnimationFrame() 告诉浏览器——你希望执行一个动画,并且要求浏览器在下次重绘之前调用指定的回调函数更新动画。该方法需要传入一个回调函数作为参数,该回调函数会在浏览器下一次重绘之前执行。

requestAnimationFrame也是个定时器,不同于setTimeout,它的时间不需要我们人为指定,这个时间取决于当前电脑的刷新率,如果是 60Hz ,那么就是 16.7ms 执行一次,如果是 120Hz 那就是 8.3ms 执行一次

fragment是虚拟文档碎片,我们一次for循环产生 20 个li的过程中可以全部把真实dom挂载到fragment上,然后再把fragment挂载到真实dom上,这样原来需要回流十万次,现在只需要回流 100000 / 20 次。

const total = 100000;
let ul = document.getElementById("container");
let once = 20;
let page = total / once;

function loop(curTotal) {
    if (curTotal <= 0) return;

    let pageCount = Math.min(curTotal, once);

    window.requestAnimationFrame(() => {
        let fragment = document.createDocumentFragment(); // 创建一个虚拟DOM碎片
        for (let i = 0; i < pageCount; i++) {
            let li = document.createElement("li");
            li.innerHTML = ~~(Math.random() * total);
            fragment.appendChild(li); // 挂载
        }
        ul.appendChild(fragment); // 回流
        loop(curTotal - pageCount);
    });
}

loop(total);