【web性能】渲染大数据量-时间分片

当我们遇到需要一次性向页面插入十万条数据的情况下,该如何保证页面不卡顿,维持一定的页面渲染性能

场景:
插入十万条数据,渲染到页面十万条数据
分析:
我们知道,UI渲染在浏览器渲染进程中属于宏任务,且涉及到页面的绘制,因此执行完当前的的脚本,进入宏任务阶段后,同时由于数据量大,整个渲染耗费时间较长
方案:

  1. 把数据分批插入到页面✅(本篇内容)
  2. 虚拟列表,渲染应该渲染的

1. 分批每次插入20条(类似于手动给他分页加载)

//需要插入的容器
let ul = document.getElementById('container');
// 插入十万条数据
let total = 100000;
// 一次插入 20 条
let once = 20;
//总页数
let page = total/once
//每条记录的索引
let index = 0;
//循环加载数据
function loop(curTotal,curIndex){
    if(curTotal <= 0){
        return false;
    }
    //每页多少条
    let pageCount = Math.min(curTotal , once);
    setTimeout(()=>{
        for(let i = 0; i < pageCount; i++){
            let li = document.createElement('li');
            li.innerText = curIndex + i + ' : ' + ~~(Math.random() * total)
            ul.appendChild(li)
        }
        loop(curTotal - pageCount,curIndex + pageCount)
    },0)
}
loop(total,index);

然而你会发现,当手速快一点时,会出现空白页、丢帧的情况;

这是为什么呢?
这里就跟浏览器的绘制频率有关系了,一般笔记本电脑的屏幕绘制频率是60Hz,也就是每隔16.7ms(1000/60≈16.7)计算机会绘制一次屏幕

在上述方案中,你的装载节点的时间点刚好在两次屏幕绘制之间,就会出现丢帧空白页面

引入requestAnimationFrame

因此,这里引入html5 提供的一个专门用于请求动画的 API:requestAnimationFrame,“请求动画帧”,接收一个回调,系统在每次屏幕绘制之前,会处理这个回调函数
这样一来,就能够同步 装载节点 与 绘制屏幕 的频率了!

对上述代码稍作改动:

//循环加载数据
function loop(curTotal,curIndex){
    if(curTotal <= 0){
        return false;
    }
    //每页多少条
    let pageCount = Math.min(curTotal , once);
    //这里换成“请求数据帧”API 
   window.requestAnimationFrame(function(){
        for(let i = 0; i < pageCount; i++){
            let li = document.createElement('li');
            li.innerText = curIndex + i + ' : ' + ~~(Math.random() * total)
            ul.appendChild(li)
        }
        loop(curTotal - pageCount,curIndex + pageCount)
    })
}
loop(total,index);

参考

优化大数据(时间分片)
requestAnimationFrame知多少

你可能感兴趣的:(【web性能】渲染大数据量-时间分片)