在本文中,我收集了一些开发技巧,以帮助您解决JavaScript动画的性能问题,并使您更容易实现在web上实现流畅移动的60fps(每秒帧数)目标。
1、避免使用昂贵的CSS属性
你是否打算使用CSS动画CSS属性转换/ CSS关键帧或JavaScript,重要的是要知道哪些属性带来的改变页面的几何(布局)——这意味着页面上的其他元素的位置将会重新计算,或将涉及绘画操作。布局和绘制任务对于浏览器来说都是非常昂贵的,特别是当你的页面上有几个元素时。因此,如果您避免对触发布局或绘制操作的CSS属性进行动画化,并坚持使用诸如转换和不透明度之类的属性,那么您将看到动画性能的显著提高,因为现代浏览器在优化这些属性方面做得非常出色。
在CSS触发器上,您将找到CSS属性的最新列表,其中包含了它们在每个现代浏览器中触发的工作的信息,包括第一次更改和随后的更改。
更改仅触发复合操作的CSS属性是优化web动画性能的一个简单而有效的步骤。
2、提升你想要的元素到他们自己的层(谨慎)
如果您想要动画的元素在它自己的compositor层上,一些现代浏览器通过将工作卸载到GPU来利用硬件加速。如果使用得当,这个动作可以对动画的表现产生积极的影响。
要将元素放在自己的层上,您需要对其进行升级。一种方法是使用CSS will-change属性。这个属性允许开发人员警告浏览器他们想要在一个元素上做出的一些更改,这样浏览器就可以提前进行必要的优化。
然而,并不是建议你在他们自己的层面上推广太多的元素,或者你是夸大其词。事实上,浏览器创建的每个层都需要内存和管理,这可能会很昂贵。
在Nick Salloum的CSS will-change属性介绍中,您可以了解如何使用will-change的细节、它的优点和缺点。
3、用requestAnimationFrame替换setTimeOut/setInterval
JavaScript动画通常使用setInterval()或setTimeout()方法。
代码像是这样的:
虽然这是可行的,但是jank的风险很高,因为回调函数在帧中的某个点(可能在最后)运行,这可能导致丢失一个或多个帧。现在,您可以使用一个为流畅的web动画(DOM animation, canvas等)定制的本地JavaScript方法,称为requestAnimationFrame()。
requestAnimationFrame()在最适合浏览器的时间执行动画代码,通常在框架的开始。
你的代码可以是这样的:
4、将事件与代码中的动画分离
以每秒60帧的速度,浏览器在每一帧上都有16.67ms来完成它的工作。这并不是很多时间,所以保持代码的精确性会对动画的流畅性产生影响。
将处理诸如滚动、调整大小、鼠标事件等事件的代码与使用requestAnimationFrame()处理屏幕更新的代码分离开来,是优化动画代码以提高性能的好方法。
5、避免长时间运行的JavaScript代码
浏览器使用主线程运行JavaScript,以及其他任务,如样式计算、布局和绘制操作。长时间运行的JavaScript代码可能会对这些任务产生负面影响,这可能导致帧被跳过,并导致janky动画。因此,简化代码肯定是确保动画平稳运行的好方法。
对于不需要访问DOM的复杂JavaScript操作,可以考虑使用Web worker。工作线程执行任务时不会影响用户界面。
6、利用浏览器的DevTools来控制性能问题
您的浏览器的开发工具提供了一种方法来监控您的浏览器在运行JavaScript代码或第三方库的过程中有多困难。它们还提供有关帧速率和更多的有用信息。
您可以通过右键单击web页面并在上下文菜单中选择Inspect来访问Chrome DevTools。
例如,使用性能工具记录web页面将使您了解该页面上的性能瓶颈:
点击录制按钮,几秒钟后停止录制:
此时,您应该有大量的数据来帮助您分析页面的性能:
Chrome DevTools指南将帮助您充分利用DevTools来分析性能,并在您的Chrome浏览器中提供大量其他类型的数据。如果Chrome不是你选择的浏览器,那也没什么大不了的,因为现在大多数浏览器都有超强大的DevTools,你可以利用它们来优化你的代码。
7、使用屏幕外的画布进行复杂的绘图操作
这个技巧与优化HTML5 Canvas的代码有关。
如果您的框架涉及复杂的绘图操作,那么一个好主意是创建一个屏幕外的画布,您在其中执行所有的绘图操作一次或仅当发生更改时,然后在每个框架上绘制屏幕外的画布。
结论
为性能优化代码是一项必要的任务,但它绝不总是简单或直接的。你的动画效果不佳可能有几个原因,但如果你尝试一下上面列出的技巧,你将会在很大程度上避免最常见的动画性能陷阱,从而改善你的网站或应用的用户体验。
领取专属 10元无门槛券
私享最新 技术干货