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

不会吧 , 不会吧 , 现在都2020年了不会还真人有人不知道JS的rAF吧???
rAF简介rAF是requestAnimationFrame的简称;
我们先从字面意思上理解requestAnimationFrame , 「request - 请求」 , 「Animation - 动画」 ,「Frame - 帧率;框架」 , rAF难道是JS的动画框架??? , 结果显而易见并不是 。 但确实rAF和动画有关系
我们先来看一下MDN官网对的requestAnimationFrame解释:
window.requestAnimationFrame() 告诉浏览器——你希望执行一个动画 , 并且要求浏览器在下次重绘之前调用指定的回调函数更新动画 。 该方法需要传入一个回调函数作为参数 , 该回调函数会在浏览器下一次重绘之前执行
浏览器兼容性
2020已经过去五分之四,你确定还不来了解一下JS的rAF?文章插图
requestAnimationFrame兼容IE10及以上 , 这时候有人会有疑问 , 怎么才到IE10啊 , 但其实我们最常使用的CSS3 animation属性也是IE10之后才有的 , 在IE9之前想要实现动画基本使用的是setTimeout/setInterval实现
作用及用法requestAnimationFrame简称rAF,它是浏览器全局对象window的一个方法 。
【2020已经过去五分之四,你确定还不来了解一下JS的rAF?】相比于setTimeout的在固定时间后执行对应的动画函数 , rAF用于指示浏览器在下一次重新绘制屏幕图像时, 执行其提供的回调函数 。
这也是rAF的最大优势–它能够保证我们的动画函数的每一次调用都对应着一次屏幕重绘 , 从而避免setTimeout通过时间定义动画频率 , 与屏幕刷新频率不一致导致的丢帧 。
详细用法requestAnimationFrame语法如下:
window.requestAnimationFrame(callback)「参数;callback」 下一次重绘之前更新动画帧所调用的函数(即上面所说的回调函数) 。 该回调函数会被传入DOMHighResTimeStamp参数 , 该参数与performance.now()的返回值相同 , 它表示requestAnimationFrame()开始去执行回调函数的时刻 。
「返回值」一个 long 整数 , 请求 ID, 是回调列表中唯一的标识 。 是个非零值 , 没别的意义 。 你可以传这个值给 window.cancelAnimationFrame() 已取消回调函数 。
DOMHighResTimeStamp 指的是一个double类型 , 用于存储毫秒级的时间值 。 这种类型可以用来描述离散的时间点或者一段时间(两个离散时间点之间的时间差) 。
performance.now()方法返回一个精确到毫秒的DOMHighResTimeStamp。
它的实际常见用法类似于setTimeout , 只是不需要设置时间间隔而已 。 如下:
const element = document.getElementById('some-element-you-want-to-animate'); let start;function step(timestamp) {// timestamp回调函数传入的`DOMHighResTimeStamp`参数 , 也就是存储毫秒级的时间值if (start === undefined)start = timestamp;const elapsed = timestamp - start;//这里使用`Math.min()`确保元素刚好停在200px的位置 。element.style.transform = 'translateX(' + Math.min(0.1 * elapsed, 200) + 'px)';if (elapsed < 2000) { // 在两秒后停止动画window.requestAnimationFrame(step);}}window.requestAnimationFrame(step);上述代码的作用在每一次屏幕显示图像的更新中 , 都将元素向左移动1px , 停在200px位置上 。
实际使用示例「上才艺 , E G M,E G M E G M E G M」
我们以在3000毫秒内移动1500px距离的动画为例
setTimeout的实现方式以下代码通过setTimeout每10毫秒为间隔时间改变一次元素的位置以实现元素的动画效果 ,当然 , 可以通过改变这个间隔时间来微调动画效果 , 可是你永远没有办法确定最优方案 , 因为它总会和刷新频率存在交叉 。
requestAnimationFrame的实现方式「从setTimeout切换到 requestAnimationFrame很容易 , 因为它们都安排了一个回调 。 对于连续动画 , 在调用动画函数之后再次调用requestAnimationFrame 。 」
request 会把每一帧中的所有DOM操作集中起来 , 在一次重绘或回流中就完成(这点很像虚拟DOM不是~) , 并且重绘或回流的时间间隔紧紧跟随浏览器的刷新频率,这样就不会出现过度渲染的问题 , 保证了流畅的需求以及浏览器的完美渲染 。
requestAnimationFrame的优点为什么不使用settimeout?setTimeout通过设定一个时间间隔来不断的更新屏幕图像 , 从而完成动图 。它的优点是可控性高 , 可以进行编码式的动画效果实现 。
setTimeout缺点:

  1. 「造成无用的函数运行开销:」
也就是过度绘制 , 同时因为更新图像的频率和屏幕的刷新重绘制步调不一致 , 会产生丢帧 , 在低性能的显示器动画看起来就会卡顿 。
  1. 「当网页标签或浏览器置于后台不可见时 , 仍然会执行 , 造成资源浪费」