>[danger]介绍一下Js中的requestAnimationFrame >[info]建议回答 * **requestAnimationFrame**是一个 JavaScript 函数,用于优化动画效果的实现。**它的调用频率通常为每秒60次**,可以在浏览器每个绘制帧之前执行回调函数,以确保动画的流畅性和响应速度,**并避免了使用 setTimeout 或 setInterval 时可能导致的性能问题**。 * 与 setTimeout 和 setInterval 相比, **requestAnimationFrame**可以更精确地控制动画的播放时间,从而保证动画的流畅性和响应速度。`setInterval`与`setTimeout`是在指定的时间间隔内重复执行一个操作,不会考虑浏览器的重绘,是按照指定的时间间隔执行回调函数,可能会被延迟执行,从而影响动画的流畅度。 * requestAnimationFrame 的回调函数只有在浏览器下一次绘制之前才执行,这意味着当页面处于非激活状态时,动画就会暂停,从而**避免了不必要的 CPU 和 GPU 资源消耗**。 * requestAnimationFrame 在绘制每一帧时,**会自动根据屏幕刷新率进行同步**,从而得到最佳的动画效果和性能表现。 >[info]技术详解 requestAnimationFrame 是一个 JavaScript 函数,用于优化动画效果的实现。它可以在浏览器每个绘制帧之前执行回调函数,以确保动画的流畅性和响应速度,**并避免了使用 setTimeout 或 setInterval 时可能导致的性能问题**。 requestAnimationFrame 的使用方法: ```javascript function animation() { // 动画逻辑代码 requestAnimationFrame(animation); } requestAnimationFrame(animation); ``` 在上述代码中,animation 函数包含动画逻辑,通过 requestAnimationFrame 不断地更新动画状态实现动画的连贯播放。由于 requestAnimationFrame 方法会在浏览器下一次绘制前执行回调函数,因此可以确保动画效果平滑且符合用户的操作反应速度,同时也不会对浏览器的性能造成太大影响。 >[info]requestAnimationFrame 的优点: 1. 与 setTimeout 和 setInterval 相比,requestAnimationFrame 可以更精确地控制动画的播放时间,从而保证动画的流畅性和响应速度。 2. requestAnimationFrame 的回调函数只有在浏览器下一次绘制之前才执行,这意味着当页面处于非激活状态时,动画就会暂停,从而避免了不必要的 CPU 和 GPU 资源消耗。 3. requestAnimationFrame 在绘制每一帧时,会自动根据屏幕刷新率进行同步,从而得到最佳的动画效果和性能表现。 需要注意的是,requestAnimationFrame 并不能完全解决所有的动画问题,有些复杂的动画仍然需要结合 CSS 过渡或者动画来实现。此外,使用 requestAnimationFrame 时也需要考虑兼容性问题,较老版本的浏览器可能不支持该方法,需要采取相应的兼容策略。 >[info]与setInterval和setTimeout对比 `requestAnimationFrame`的调用频率通常为每秒60次。这意味着我们可以在每次重绘之前更新动画的状态,并确保动画流畅运行,而不会对浏览器的性能造成影响。 `setInterval`与`setTimeout`它可以让我们在指定的时间间隔内重复执行一个操作,不会考虑浏览器的重绘,而是按照指定的时间间隔执行回调函数,可能会被延迟执行,从而影响动画的流畅度。 >效果对比 我们设置了两个容器,分别用`requestAnimationFrame()`方法和`setTimeout`方法进行平移效果,Js 代码如下所示: ``` let distance = 0 let box = document.getElementById('box') let box2 = document.getElementById('box2') window.addEventListener('click', function () { requestAnimationFrame(function move() { box.style.transform = `translateX(${distance++}px)` requestAnimationFrame(move)//递归 }) setTimeout(function change() { box2.style.transform = `translateX(${distance++}px)` setTimeout(change, 17) }, 17) }) ``` 效果图如下: ![](https://img.kancloud.cn/7d/9c/7d9cfd5187617f97f79e4e9b22e6fb8d_960x422.webp) 可能我们肉眼看得不是很清楚,但是确实下面的图形平移没有上面图形流畅,用`setTimeout`会有卡顿现象。