var progress = 0 //回调函数 function render() { progress += 1 //修改图像的位置 if (progress < 100) { //在动画没有结束前,递归渲染 window.requestAnimationFrame(render) } } //第一帧渲染 window.requestAnimationFrame(render)
优点:
CPU 节能:使用 setTimeout 实现的动画,当页面被隐藏或最小化时,setTimeout 仍然在后台执行动画任务,由于此时页面处于不可见或不可用状态,刷新动画是没有意义的,完全是浪费 CPU 资源。而 requestAnimationFrame 则完全不同,当页面处理未激活的状态下,该页面的屏幕刷新任务也会被系统暂停,因此跟着系统步伐走的 requestAnimationFrame 也会停止渲染,当页面被激活时,动画就从上次停留的地方继续执行,有效节省了 CPU 开销。
//需要插入的容器 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)
//需要插入的容器 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) 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)
var lastTime = performance.now() var frame = 0 var lastFameTime = performance.now() var loop = function (time) { var now = performance.now() var fs = now - lastFameTime lastFameTime = now var fps = Math.round(1000 / fs) frame++ if (now > 1000 + lastTime) { var fps = Math.round((frame * 1000) / (now - lastTime)) frame = 0 lastTime = now } window.requestAnimationFrame(loop) }