在这里的话我们采用的是两个api
createDocumentFragment() :
createdocumentfragment()方法创建了一虚拟的节点对象,节点对象包含所有属性和方法。注意如果我们向这个虚拟节点中插入数据是不损耗性能的
requestAnimationFrame() :
【1】requestAnimationFrame会把每一帧中的所有DOM操作集中起来,在一次重绘或回流中就完成,并且重绘或回流的时间间隔紧紧跟随浏览器的刷新频率
【2】在隐藏或不可见的元素中,requestAnimationFrame将不会进行重绘或回流,这当然就意味着更少的CPU、GPU和内存使用量
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>如何渲染10万条数据不卡顿</title>
</head>
<body>
<!-- 首先我们创建一个 载体用于数据填充 -->
<ul></ul>
</body>
</html>
<script>
// 总渲染数据条数
var count = 100000
// 每次渲染的条数
var twice = 20
// 获取总共需要渲染的次数 向上取整
var totalTwice = Math.ceil(count / twice)
// ul节点
var ul = document.querySelector('ul')
// 用于判断当前执行了多少次
var countLoop = 0
// 创建一个添加函数
function add() {
// 首先创建一个createDocumentFragment 这个是一个虚拟节点,像虚拟节点中插入数据不消耗性能
const wDom = document.createDocumentFragment()
for (let index = 0; index < twice; index++) {
var li = document.createElement('li')
li.innerHTML = Math.floor(Math.random() * 10000 + 1)
wDom.appendChild(li)
}
// 直接for循环完,因为for循环向虚拟节点中插入数据是不损耗性能的,其实相当于只是在插入ul时才真正的做了节点操作
// 相当于执行了100000/20次 插入才做而不是执行了100000次操作 这样并不会说造成卡顿卡死的情况
ul.appendChild(wDom)
countLoop++
look()
}
function look() {
if (countLoop < count) {
// window.requestAnimationFrame() 告诉浏览器——你希望执行一个动画,
// 并且要求浏览器在下次重绘之前调用指定的回调函数更新动画。
// 该方法需要传入一个回调函数作为参数,该回调函数会在浏览器下一次重绘之前执行
window.requestAnimationFrame(add)
}
}
look()
</script>