学习自渡一
工作中遇到过需要批量操作页面上大量dom的情况,结果就是页面出现长时间卡顿,如今了解到或可以通过一个Api(requestIdleCallback)解决这类问题,知识的广度很重要!
这里以在页面上插入10W个数为案例,如果简单粗暴的通过for循环来执行,必然会出现页面卡顿,如果数字太多,甚至可能导致该标签页崩溃。
<!doctype html>
<html>
<head>
<meta charset="UTF-8">
</head>
<body>
<button id="btn">插入10W个数</button>
</body>
<script>
let btn = document.querySelector('#btn')
// 生成一个0~99999的数组
let datas = new Array(100000).fill(0).map((_, i) => i)
btn.onclick = () => {
// 这段代码执行起来效果感人
// 浏览器会一直等待任务执行完成后再执行渲染
// 导致页面出现长时间无变化
// 容易让用户误解操作失败或页面卡死
// for (let i of datas) {
// const div = document.createElement('div')
// div.innerText = i
// document.body.appendChild(div)
// }
insert(datas)
}
function insert(datas) {
if (datas.length === 0) {
return
}
let i = 0
function run() {
// 由于浏览器是每隔一段时间执行一次渲染
// 通过该Api可以将一个长任务进行切片,保证每次渲染都能执行一个分片
// 浏览器会在空闲时调用传入的函数
requestIdleCallback((idle) => {
// 还有剩余空闲时间就向页面插入元素
while (idle.timeRemaining() > 0 && i < datas.length ) {
const div = document.createElement('div')
div.innerText = i
document.body.appendChild(div)
i++
}
run()
})
}
run()
}
</script>
</html>