java系统找不到指定文件怎么解决
482
2022-08-23
使用 requestAnimationFrame 提升 web 性能
requestAnimationFrame 与延时执行函数 setTimeout 类似,但不用设置时间,即可将操作延迟至下一次网页重绘时执行。
requestAnimationFrame 的用法
延迟到下一帧执行
requestAnimationFrame(回调函数)
功能:将回调函数,延迟到下一帧(下一次网页重绘)前执行。
每一帧都执行
在回调函数内再次调用 requestAnimationFrame()
requestAnimationFrame(function update() { console.log("执行了更新!"); // requestAnimationFrame 的回调函数默认只会被调用一次,如果希望每帧都执行,则每帧都需要调用 requestAnimationFrame(update);});
取消执行
requestAnimationFrame(回调函数) 会返回一个整数(定时器的编号),将其传给cancelAnimationFrame(定时器的编号) 可取消回调函数的执行,如:
// 定义定时器let timer1 = requestAnimationFrame(回调函数)// 取消定时器cancelAnimationFrame(timer1)
requestAnimationFrame 的常见应用场景
提升 web 性能
使用 requestAnimationFrame 替换 setTimeout 和 setInterva 可提升web性能。
setTimeout 和 setInterva 实现动画的缺点
时间不精确,通常实际执行时间都要比其设定的时间晚一些。实现的动画在某些低端机上会出现卡顿、抖动的现象。(不同设备的屏幕刷新频率不同,而 setTimeout 和 setInterva 只能设置一个固定的时间间隔,这个时间和屏幕的刷新时间不同时,就会出现掉帧,而导致页面卡顿、抖动)
requestAnimationFrame 实现动画的优势
requestAnimationFrame 采用系统时间间隔,保持最佳绘制效率,不会因为间隔时间过短,造成过度绘制,增加开销;也不会因为间隔时间太长,使动画卡顿不流畅,让各种网页动画效果能够有一个统一的刷新机制,从而节省系统资源,提高系统性能,改善视觉效果。
全局监听浏览器滚动事件
// 全局监听浏览器滚动事件window.onscroll = function () { requestAnimationFrame(function scroll() { console.log("页面滚动了"); });};
平滑滚动
function scrollToTop() { const c = document.documentElement.scrollTop || document.body.scrollTop; if (c > 0) { window.requestAnimationFrame(scrollToTop); window.scrollTo(0, c - c / 8); }}
大量数据的渲染
比如十万条数据的渲染,使用 requestAnimationFrame 分页加载。
//需要插入的容器let ul = document.getElementById('container')// 插入十万条数据let total = 100000// 一次插入 20 条let once = 20//总页数let page = total / once//每条记录的索引let index = 0//循环加载数据function loop(curTotal,) { 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)
使用 setTimeout 实现的写法如下:
//需要插入的容器let ul = document.getElementById('container')// 插入十万条数据let total = 100000// 一次插入 20 条let once = 20//总页数let page = total / once//每条记录的索引let index = 0//循环加载数据function loop(curTotal,) { 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)
监控页面的卡顿
比如连续出现 3 个低于 20 的 FPS 即可认为网页存在卡顿。
var lastTime = performance.now()var frame = 0var 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)}
requestAnimationFrame 的优点
requestAnimationFrame 会把每一帧中所有的DOM操作集中起来,在一次重绘/回流中完成。
重绘:当某个元素颜色样式发生更改时(如背景颜色、文字颜色),页面也需要更新,浏览器需要重新绘制元素,称为重绘(repaint)。回流:当页面上的某一个元素的大小或者位置发生更改时,都会影响到与它相邻元素的状况,甚至整个页面的元素状态(位置、元素大小)都需要重新计算和更新。这种操作称为回流(reflow)或者布局(layout)。一个页面至少会有一次回流,就是在页面初始化时。
requestAnimationFrame 重绘/回流的时间间隔紧紧跟随浏览器的刷新频率。充分利用了显示器的刷新机制,比较节省系统资源(显示器有固定的刷新频率60Hz/75Hz,即每秒最多重绘60次或75次,requestAnimationFrame的执行紧跟着系统的绘制频率走,便能保证回调函数在屏幕每一次的绘制间隔中只被执行一次,这样就不会引起丢帧现象,也不会导致动画出现卡顿的问题)。对隐藏或不可见的元素,requestAnimationFrame不会进行重绘/回流,这意味着更少的CPU、GPU和内存使用量。当页面被隐藏或最小化时,requestAnimationFrame会停止渲染(setTimeout 和setInterval 仍然在后台执行动画任务),当页面被激活时,动画会从上次停留的地方继续执行,有效节省了CPU、GPU和电力开销。requestAnimationFrame是由浏览器专门为动画提供的API,在运行时浏览器会自动优化方法的调用
requestAnimationFrame 的缺点
requestAnimationFrame 存在兼容性问题,在不支持的浏览器(如 IE9),需添加兼容代码requestAnimationFrame 使用的主线程,若主线程非常繁忙,requestAnimationFrame的动画效果会大打折扣。
兼容写法
对不支持 requestAnimationFrame 的浏览器(如 IE9),需在代码前添加以下兼容代码:
if(!window.requestAnimationFrame){ var lastTime = 0; window.requestAnimationFrame = function(callback){ var currTime = new Date().getTime(); var timeToCall = Math.max(0,16.7-(currTime - lastTime)); var id = window.setTimeout(function(){ callback(currTime + timeToCall); },timeToCall); lastTime = currTime + timeToCall; return id; }}
版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。
发表评论
暂时没有评论,来抢沙发吧~