2020已经过去五分之四,你确定还不来了解一下JS的rAF?( 二 )

  • 「API本身达不到毫秒级的精确:」
  • 如果使用 setTimeout或者setInterval 那么需要我们制定时间 假设给予 (1000/60)理论上就可以完成60帧速率的动画 。 所以事实是浏览器可以“强制规定时间间隔的下限(clamping th timeout interval)”,一般浏览器所允许的时间在5-10毫秒 , 也就是说即使你给了某个小于10的数 , 可能也要等待10毫秒 。
    1. 「浏览器不能完美执行:」
    当动画使用10ms的settimeout绘制动画时 , 您将看到一个时序不匹配 , 如下所示 。
    2020已经过去五分之四,你确定还不来了解一下JS的rAF?文章插图
    我们的显示屏一般是「16.7ms(即60FPS)的显示频率」 , 上图的第一行代表大多数监视器上显示的「16.7ms显示频率」 , 上图的第二行代表「10ms的典型setTimeout」 。 由于在显示刷新间隔之前发生了另一个绘制请求 , 因此无法绘制每次的第三个绘制(红色箭头指示) 。 这种透支会导致动画断断续续 , 「因为每三帧都会丢失」 。 计时器分辨率的降低也会对电池寿命产生负面影响 , 并降低其他应用程序的性能 。
    如果使用requestAnimationFrame可以解决setTimeout的丢帧问题 , 因为它使应用程序时通知(且仅当)的浏览器需要更新页面显示 , 渲染时间由系统处理 。 因此 , 应用程序与浏览器绘画间隔完全一致 , 并且仅使用适当数量的资源 。
    requestAnimationFrame的好处相比于setTimeout的在固定时间后执行对应的动画函数 , requestAnimationFrame用于指示浏览器在下一次重新绘制屏幕图像时, 执行其提供的回调函数 。
    • 「使浏览器画面的重绘和回流与显示器的刷新频率同步」它能够保证我们的动画函数的每一次调用都对应着一次屏幕重绘 , 从而避免setTimeout通过时间定义动画频率 , 与屏幕刷新频率不一致导致的丢帧 。
    • 「节省系统资源 , 提高性能和视觉效果」在页面被置于后台或隐藏时 , 会自动的停止 , 不进行函数的执行 , 当页面激活时 , 会重新从上次停止的状态开始执行 , 因此在性能开销上也会相比setTimeout小很多 。
    兼容问题目前的时间点上 , 几乎所有的浏览器现行版本都支持了requestAnimationFrame函数 。 但在一部分浏览器上还需要加上兼容性前缀 。下面这是比较全面的方法用来使requestAnimation兼容各浏览器:
    (function() {var lastTime = 0;var vendors = ['webkit', 'moz']; // 浏览器前缀// 当window.requestAnimationFrame不存在时执行for循环 , 添加前缀for(var x = 0; x < vendors.length++x) {window.requestAnimationFrame = window[vendors[x] + 'RequestAnimationFrame'];window.cancelAnimationFrame = window[vendors[x] + 'CancelAnimationFrame'] ||window[vendors[x] + 'CancelRequestAnimationFrame'];}//当添加前缀后依旧不存在 , 则使用setTimeout替代if (!window.requestAnimationFrame) {window.requestAnimationFrame = function(callback, element) {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;};}if (!window.cancelAnimationFrame) {window.cancelAnimationFrame = function(id) {clearTimeout(id);};}}());然后 , 我们就可以以使用setTimeout的感觉使用requestAnimationFrame方法制作动画啦!
    结尾如有疑问 , 可在下方留言 , 会第一时间进行回复
    谢谢你愿意花时间阅读这篇文章 , 希望可以对你有所帮助!
    最后 , 小编想说:我是一名python开发工程师 ,
    整理了一套最新的python系统学习教程 ,
    想要这些资料的可以关注私信小编“01”即可 , 希望能对你有所帮助 。