浏览器不支持回调_requestAnimationFrame()对动画的良好支持

一、早期动画循环的缺点

早期创建动画循环的方式是使用setInterval()方法来控制所有动画:

(function(){
    setInterval(() => {
        console.log("animation...");
    }, 1000/60);
})();

编写这种动画循环的关键是要知道延迟时间多长合适:

  • 一方面,循环间隔必须足够短,这样才能让不同的动画效果显得更平滑流畅。
  • 另一方面,循环间隔还要足够长,这样才能确保浏览器有能力渲染产生的变化。

大多数电脑显示器的刷新频率是60Hz,大概相当于每秒钟重绘60次。大多数浏览器都会对重绘操作加以限制,不超过显示器的重绘频率,因为即使超过那个频率用户体验也不会有提升。

因此,最平滑动画的最佳循环间隔是1000ms/60,约等于17ms。以这个循环间隔重绘的动画是最平滑的,因为这个速度最接近浏览器的最高限速。

但是,无论setInterval()还是setTimeout()都不十分精确。为它们传入的第二个参数,实际上只是指定了动画代码添加到浏览器UI线程队列中以等待执行的时间。如果UI线程繁忙,比如忙于处理用户操作,那么即使把代码加入队列也不会立即执行。

二、requestAnimationFrame()

requestAnimationFrame最大的优势是由系统来决定回调函数的执行时机。具体一点讲,如果屏幕刷新率是60Hz,那么回调函数就每16.7ms被执行一次,如果刷新率是75Hz,那么这个时间间隔就变成了1000/75=13.3ms,换句话说就是,requestAnimationFrame的步伐跟着系统的刷新步伐走。它能保证回调函数在屏幕每一次的刷新间隔中只被执行一次,这样就不会引起丢帧现象,也不会导致动画出现卡顿的问题。

而且为了提高性能和电池寿命,在大多数浏览器里,当requestAnimationFrame() 运行在后台标签页或者隐藏的<iframe> 里时,requestAnimationFrame() 会被暂停调用以提升性能和电池寿命。

回调函数会被传入DOMHighResTimeStamp参数,DOMHighResTimeStamp指示当前被 requestAnimationFrame() 排序的回调函数被触发的时间。

示例:

var startTime = Date.now();
(function animation(timestamp) {
    let diff = timestamp - startTime;
    startTime = timestamp;
    console.log(diff);
    requestAnimationFrame(animation);
})();

可以发现,循环间隔几乎都是16ms左右:

628ce7d41e3c754aee75fd9b417b1f76.png
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值