requestAnimationFrame的动画循环

requestAnimationFrame 是一种浏览器优化的动画实现方式,与显示器刷新频率同步,避免过度绘制和资源浪费。它解决了setTimeout和setInterval不精确的问题,提供更平滑的动画效果。当页面非激活状态时,requestAnimationFrame会自动暂停,节省资源。基本用法是传入一个回调函数,该函数在重绘前被调用来更新DOM样式。若要取消动画,可使用cancelAnimationFrame。
摘要由CSDN通过智能技术生成

首先总结一下在前端开发中实现动画的方式:

  • CSS3的animattion+keyframes;
  • CSS3的transition过渡效果;
  • 通过在canvas上作图来实现动画;
  • 借助jQuery动画相关的API方便地实现;
  • 使用window.setTimout()或者window.setInterval()通过不断更新元素的状态位置等来实现动画,前提是画面的更新频率要达到每秒60次才能让肉眼看到流畅的动画效果;
  • 使用window.requestAnimationFrame()方法。

初识requestAnimationFrame

requestAnimationFrame 解决了浏览器不知道javascript动画什么时候开始、不知道最佳循环间隔时间的问题。它是跟着浏览器的绘制走的,如果浏览器绘制间隔是16.7ms,它就按这个间隔绘制;如果浏览器绘制间隔是10ms, 它就按10ms绘制。这样就不会存在过度绘制的问题,动画不会丢帧。
内部是这么运作的:
浏览器页面每次要重绘,就会通知requestAnimationFrame;
这是资源非常高效的一种利用方式。怎么讲呢?有以下两点:

  • 就算很多个requestAnimationFrame()要执行,浏览器只要通知一次就可以了。而setTimeout是多个独立绘制。
  • 一旦页面不出于当前页面(比如:页面最小化了),页面是不会进行重绘的,自然requestAnimationFrame也不会触发(因为没有通知)。页面绘制全部停止,资源高效利用。
    编写动画循环的关键:是要知道延迟时间多长合适。一方面,循环间隔必须足够短,这样才能保证不同的动画效果显得更平滑流畅;另一方面,循环间隔还要足够长,这样才能保证浏览器有能力渲染产生的变化。大多数显示器的刷新频率是60Hz,相当于每秒钟重绘60次。大多数浏览器都会对重绘操作加以限制,不超过显示器的重绘频率,因为即使超过了这个频率,用户体验也不会有提升。
    因此,最平滑动画的最佳循环间隔是1000ms/60,约等于17ms。以这个循环间隔重绘的动画是平滑的,因为这个速度最接近浏览器的最高限速。为了适应17ms的循环间隔,多重动画可能需要加以节制,以便不会完成得太快。
    虽然与使用多组 setTimeout() 相比,使用 setInterval() 的动画循环效率更高。但是无论 setTimeout() 还是 setInterval() 都不十分精确。为它们传入的第二个参数,实际上只是指定了把动画代码添加到浏览器UI线程队列以等待执行的时间。如果队列前面已经加入了其他任务,那动画代码就要等前面的任务执行完成后再执行。如果UI线程繁忙,比如忙于处理用户操作,那么即使把代码加入队列也不会立即执行
    因此,知道什么时候绘制下一帧是保证动画平滑的关键。然而,面对不十分精确的 setTimeout( )和 setInterval() ,开发人员至今都没有办法确保浏览器按时绘制下一帧。以下是几个浏览器的计时器精度:
    IE8及其以下版本浏览器: 15.6ms;
    IE9及其以上版本浏览器:4ms;
    Firefox和Safari:10ms;
    Chrome:4ms。
    更为复杂的是,浏览器开始限制后台标签页或不活动标签页的计数器。因此,即使你优化了循环间隔,可能仍然只能接近你想要的效果。

CSS3动画的优势在于浏览器知道动画什么时候开始,因此会计算出正确的循环间隔,在适当的时候刷新UI。而对于JavaScript动画,浏览器就无从知晓什么时候开始。
在JS中,我们可以通过requestAnimationFrame( )方法告诉浏览器某些代码将要执行动画。这样浏览器可以在运行某些代码后进行适当的优化。
与 setTimeout() 和 setInterval() 方法不同,requestAnimationFrame( )不需要调用者指定帧速率,浏览器会自行决定最佳的帧效率
requestAnimationFrame是浏览器用于定时循环操作的一个接口,类似于setTimeout,主要用途是按帧对网页进行重绘
设置这个API的目的是:为了让各种网页动画效果(DOM动画、Canvas动画、SVG动画、WebGL动画)能够有一个统一的刷新机制,从而节省系统资源,提高系统性能,改善视觉效果。代码中使用这个API,就是告诉浏览器希望执行一个动画,让浏览器在下一个动画帧安排一次网页重绘
requestAnimationFrame的优势:在于充分利用显示器的刷新机制,比较节省系统资源。显示器有固定的刷新频率(60Hz或75Hz),也就是说,每秒最多只能重绘60次或75次,requestAnimationFrame的基本思想就是与这个刷新频率保持同步,利用这个刷新频率进行页面重绘。此外,使用这个API,一旦页面不处于浏览器的当前标签,就会自动停止刷新。这就节省了CPU、GPU和电力。

requestAnimationFrame() 方法接收一个参数(一个函数

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值