多应用+插件架构,代码干净,二开方便,首家独创一键云编译技术,文档视频完善,免费商用码云13.8K 广告
>本小节主要讲述动画帧率相关内容 <br /> ### 使用chrome开发者工具performance ![](https://box.kancloud.cn/0c375e328842bd967a62d19166f16c5c_1439x503.png) <br /> ![](https://box.kancloud.cn/6009a01081c3631957da1672d763dec1_1439x197.png) 第二张图显示的是帧率相关的内容,绿色的柱状条跟动画的帧率有关,越高说明帧率越高,红色的为动画卡顿。 <br /> ### 相关api #### window.requestAnimationFrame() 用来将某一动画放置在下一次渲染时执行,在页面同时处理很多动画的情况下可以提交动画的帧率。 举个🌰:比如循环某一dom元素数组,讲其高度提高至原来的两倍 ```javascript function doubleHeight(element) { let currentHeight = element.clientHeight; element.style.height = (currentHeight \* 2) + 'px'; } elements.forEach(doubleHeight); ``` 上面代码的问题在于,for循环的速度很快,导致在一个渲染中出现很多个提高高度的动画,导致页面性能降低,可以通过使用该api进行改进 ```javascript function doubleHeight(element) { let currentHeight = element.clientHeight; window.requestAnimationFrame(() => { element.style.height = (currentHeight \* 2) + 'px'; }) } elements.forEach(doubleHeight); ``` 该api接受一个回调函数,回调函数将在下一次渲染时执行,这样我们就将多次并行的渲染改成了串行的渲染,该api多用于对动画的渲染速度的调节; 例如我们在页面滚动要执行一些动画 ```javascript window.onscroll = function () { window.requestAnimationFrame(/\*回调函数\*/) } ``` 例如使元素每一帧旋转一度 ```javascript let targetEle = document.getElelementById('demo'); function rotateFn (arc) { targetEle.style.transform = `rotate: ${arc}deg`; // eslint不推荐使用++或者--的方式,建议养成这个习惯 window.requestAnimationFrame(rotateFn(arc += 1)) } window.requestAnimationFrame(rotateFn(0)) ``` #### window.requestIdleCallback( ) - 只有chrome有 该方法用于将动画放置在页面渲染空闲时间执行,可以分摊动画渲染高峰时期的渲染引擎的压力,当只有帧的末尾有空闲时间时,回调才会执行。 其接受两个参数,第一个时要执行的回调函数,第二是时间,用于强制设定渲染时间。通过设定第二个时间可以实现设定时间内没有空闲时间去渲染时,会强制渲染,无需继续等待。 ```javascript // 在3s内如果一直在等待渲染,那么3s后将强制渲染,不再等待。 window.requestIdleCallback(() => { // ...动画效果 }, 3000) ``` 同时,第一个回调函数可以接受一个名为deadline的对象作为参数,该对象有两个属性,分别为timeRemaining()和didTimeout - deadline.timeRemaining( )是一个只读方法,用于返回当前帧后剩余的毫秒数,可以用于判断当前帧是否有时间去执行我们要执行的动画 - didTimeout返回一个布尔值,用于表明我们指定的时间是否到期。 在实际使用中会将这两个参数结合起来使用 ```javascript function runAnimation (deadline) { // 如果帧后剩余时间大于0或者设定的时间已经到期,立即执行动画 if (deadline.timeRemaining() > 0 || deadline.didTimeout) { //...执行动画 } // 否则就将动画放到下一帧去执行 else { window.requestIdleCallback(runAnimation(deadline)) } } window.requestIdleCallback(runAnimation(deadline), 3000) ```