页面加载海量数据
2019-10-09 本文已影响0人
方_糖
题目参考 https://juejin.im/post/5ae17a386fb9a07abc299cdd
题目
10w 条记录的数组,一次性渲染到页面上,如何处理可以不冻结UI?
具体化
页面上有个空的无序列表节点 ul ,其 id 为box ,现需要往列表插入 10w 个 li
分析
1. 一般写法:直接循环添加所有的li:
var div=document.getElementById('box');
for(var i = 0; i < 100000; i++){
var li=document.createElement('li');
div.append(li);
}
一般写法的性能测试图
2. 使用DocumentFragment
的写法:
DocumentFragment参考 : https://developer.mozilla.org/zh-CN/docs/Web/API/DocumentFragment
DocumentFragment
不是真实 DOM 树的一部分,它的变化不会触发 DOM 树的重新渲染,且不会导致性能等问题。
var div=document.getElementById('box');
var documentFragment=document.createDocumentFragment()
for(var i = 0; i < 100000; i++){
var li=document.createElement('li');
documentFragment.append(li);
}
div.append(documentFragment)
使用`DocumentFragment`的性能测试图
3. 使用DocumentFragment
+ requestAniminationFrame
进行分段渲染
requestAniminationFrame
参考: https://www.zhangxinxu.com/wordpress/2013/09/css3-animation-requestanimationframe-tween-动画算法/
requestAnimationFrame
相当于setTimeout,但是他会自己设定时间(时间间隔为浏览设备绘制间隔:这样就不会有掉帧问题)
var div=document.getElementById('box');
var num=100000;
var batchSize = 10; //每次渲染的个数
var batchCount = Math.ceil(num / batchSize); //渲染次数
var batchDone = 0; //渲染完成的个数
function render(){
var documentFragment=document.createDocumentFragment(); //DocumentFragment 不是真实 DOM 树的一部分,它的变化不会触发 DOM 树的重新渲染,且不会导致性能等问题
for(let i = 0; i < batchSize; i++ ){
var li=document.createElement('li');
documentFragment.append(li);
}
div.append(documentFragment);
batchDone++;
//console.log(batchDone)
doRender();
}
//分批渲染
function doRender(){
if(batchDone < batchCount){
//由于是分批渲染,所以会导致总的时间会增多
window.requestAnimationFrame(render); //requestAnimationFrame相当于setTimeout,但是他会自己设定时间(时间间隔为浏览设备绘制间隔:这样就不会有掉帧问题)
}
}
doRender();
分批渲染性能测试图
虽然分批渲染的性能在这里和普通渲染的性能相当,但是在数据越多的时候,普通渲染时可能会出现长时间的空白等待时间 ,但是分批渲染虽然渲染时间也长,但不会影响用户的操作。