前言
在实际工作中,我们很少会遇到一次性需要向页面中插入大量数据的情况,但是为了丰富我们的知识体系,我们有必要了解并清楚当遇到大量数据时,如何才能在不卡主页面的情况下渲染数据,以及其中背后的原理。
对于一次性插入大量数据的情况,一般有两种做法:
- 时间分片
- 虚拟列表
本文作为开篇,着重来介绍如何使用时间分片
的方式来渲染大量数据,虚拟列表相关的内容,日后会持续整理。
最粗暴的做法(一次性渲染)
我们先来看看最粗暴的做法,一次性将大量数据插入到页面中:
<ul id="container"></ul>
复制代码
// 记录任务开始时间
let now = Date.now();
// 插入十万条数据
const total = 100000;
// 获取容器
let ul = document.getElementById('container');
// 将数据插入容器中
for (let i = 0; i < total; i++) {
let li = document.createElement('li');
li.innerText = ~~(Math.random() * total)
ul.appendChild(li);
}
console.log('JS运行时间:',Date.now() - now);
setTimeout(()=>{
console.log('总运行时间:',Date.now() - now);
},0)
// print: JS运行时间: 187
// print: 总运行时间: 2844
复制代码
我们对十万条记录进行循环操作,JS的运行时间为187ms
,还是蛮快的,但是最终渲染完成后的总时间确是2844ms
。
简单说明一下,为何两次console.log
的结果时间差异巨大,并且是如何简单来统计JS运行时间
和总渲染时间
:
- 在 JS 的
Event Loop
中,当JS引擎所管理的执行栈中的事件以及所有微任务事件全部执行完后,才会触发渲染线程对页面进行渲染 - 第一个
console.log
的触发时间是在页面进行渲染之前,此时得到的间隔时间为JS运行所需要的时间 - 第二个
console.log
是放到 setTimeout 中的,它的触发时间是在渲染完成,在下一次Event Loop
中执行的