关键要点
transform
和 opacity
。will-change
属性将要进行动画处理的元素提升到它们自己的图层,但这应该谨慎操作,因为它需要内存和管理。requestAnimationFrame
替换 setTimeout/setInterval
,以减少卡顿的风险并确保动画更流畅,因为此方法会在最适合浏览器的时机执行动画代码。网页动画的作用已经从简单的装饰性效果发展到在用户体验中发挥具体作用——例如,在用户与您的应用程序交互时提供视觉反馈,引导用户关注以实现应用程序的目标,提供帮助用户理解应用程序界面的视觉提示等等。
为了确保网页动画能够胜任这些关键任务,重要的是运动必须在正确的时间以流畅的方式进行,以便用户将其视为辅助,而不是妨碍他们在应用程序上尝试执行的任何操作。
糟糕的动画设计会导致一个令人讨厌的效果——卡顿(jank),jankfree.org 对其解释如下:
现代浏览器试图与设备的刷新率同步刷新屏幕上的内容。对于当今大多数设备而言,屏幕每秒刷新 60 次,或 60Hz。如果屏幕上有一些运动(例如滚动、过渡或动画),浏览器应该每秒创建 60 帧以匹配刷新率。卡顿是用户在网站或应用程序跟不上刷新率时看到的任何卡顿、抖动或简单的停顿。
如果动画卡顿,用户最终会越来越少地与您的应用程序交互,从而对其成功产生负面影响。显然,没有人想要那样。
在本文中,我收集了一些性能技巧,以帮助您解决 JavaScript 动画问题,并更轻松地达到 60fps(每秒帧数)的目标,从而在网络上实现流畅的运动。
1. 避免对代价高昂的 CSS 属性进行动画处理
无论您计划使用CSS 过渡/CSS 关键帧还是JavaScript 来对CSS 属性进行动画处理,了解哪些属性会导致页面几何形状发生变化(布局)——这意味着必须重新计算页面上其他元素的位置,或者会涉及绘制操作——这一点非常重要。布局和绘制任务对于浏览器来说处理起来非常昂贵,尤其是在页面上有多个元素的情况下。因此,如果您避免对触发布局或绘制操作的CSS 属性进行动画处理,并坚持使用诸如transform
和opacity
之类的属性,则会看到动画性能显着提高,因为现代浏览器在优化这些属性方面做得非常出色。
在 CSS Triggers 上,您可以找到一个最新的 CSS 属性列表,其中包含有关它们在每个现代浏览器中触发的操作的信息,包括第一次更改和后续更改。
更改仅触发合成操作的 CSS 属性是您可以采取的优化网页动画性能的简单有效步骤。
2. 将要进行动画处理的元素提升到它们自己的图层(谨慎操作)
如果要进行动画处理的元素位于它自己的合成器图层上,一些现代浏览器会利用硬件加速将工作卸载到 GPU。如果使用得当,此举可以对动画的性能产生积极影响。
要使元素位于它自己的图层上,您需要提升它。一种方法是使用 CSS will-change
属性。此属性允许开发人员提前警告浏览器他们想要对元素进行的一些更改,以便浏览器可以提前进行必要的优化。
但是,不建议您将太多元素提升到它们自己的图层上,或者夸大其词地这样做。事实上,浏览器创建的每个图层都需要内存和管理,这可能是昂贵的。
您可以在 Nick Salloum 的《CSS will-change 属性简介》中了解如何使用 will-change
、它的优点和缺点的详细信息。
3. 使用 requestAnimationFrame
替换 setTimeout/setInterval
JavaScript 动画通常使用 setInterval()
或 setTimeout()
进行编码。
代码如下所示:
<code class="language-javascript">var timer; function animateElement() { timer = setInterval(function() { // 动画代码在此处 }, 2000); } // 要停止动画,请使用 clearInterval function stopAnimation() { clearInterval(timer); }</code>
虽然这有效,但卡顿的风险很高,因为回调函数在帧中的某个时间点运行,可能在最后,这可能导致错过一帧或多帧。如今,您可以使用一种专为流畅网页动画(DOM 动画、画布等)设计的原生 JavaScript 方法,称为 requestAnimationFrame()
。
requestAnimationFrame()
在最适合浏览器的时机执行您的动画代码,通常在帧的开头。
您的代码可能如下所示:
<code class="language-javascript">var timer; function animateElement() { timer = setInterval(function() { // 动画代码在此处 }, 2000); } // 要停止动画,请使用 clearInterval function stopAnimation() { clearInterval(timer); }</code>
SitePoint 上 Tim Evko 的《使用 requestAnimationFrame 提高性能》提供了一个关于使用 requestAnimationFrame()
进行编码的精彩视频介绍。
4. 在代码中将事件与动画解耦
在每秒 60 帧的情况下,浏览器在每一帧上只有 16.67ms 来完成它的工作。时间不多,因此保持代码精简可能会对动画的流畅性产生影响。
将处理滚动、调整大小、鼠标事件等事件的代码与使用 requestAnimationFrame()
处理屏幕更新的代码解耦,是优化动画代码性能的好方法。
有关此优化技巧和相关示例代码的深入讨论,请查看 Paul Lewis 的《使用 requestAnimationFrame 创建更精简、更强大、更快的动画》。
5. 避免长时间运行的 JavaScript 代码
浏览器使用主线程来运行 JavaScript,以及其他任务,例如样式计算、布局和绘制操作。长时间运行的 JavaScript 代码可能会对这些任务产生负面影响,这可能导致帧被跳过并导致动画卡顿。因此,简化代码肯定是一种确保动画流畅运行的好方法。
对于不需要访问 DOM 的复杂 JavaScript 操作,请考虑使用 Web Workers。工作线程执行其任务不会影响用户界面。
6. 利用浏览器的开发者工具来控制性能问题
浏览器的开发者工具提供了一种方法来监控浏览器运行您的 JavaScript 代码或第三方库的难度。它们还提供有关帧速率等的实用信息。
您可以通过右键单击网页并在上下文菜单中选择“检查”来访问 Chrome DevTools。例如,使用性能工具记录您的网页将使您深入了解该页面上的性能瓶颈:
单击“记录”按钮,然后在几秒钟后停止记录:
此时,您应该拥有大量数据来帮助您分析页面的性能:
本 Chrome DevTools 指南将帮助您充分利用 DevTools 来分析 Chrome 浏览器中的性能和许多其他类型的数据。如果 Chrome 不是您选择的浏览器,这没关系,因为如今大多数现代浏览器都配备了功能强大的 DevTools,您可以利用它们来优化代码。
7. 对于复杂的绘图操作,使用离屏画布
此技巧专门与优化 HTML5 Canvas 代码有关。
如果您的帧涉及复杂的绘图操作,一个好主意是在其中执行所有绘图操作一次或仅在发生更改时执行一次,然后在每一帧上仅绘制离屏画布。
您可以在 MDN 的《优化 Canvas》文章中找到与该技巧相关的详细信息和代码示例以及更多内容。
结论
如果您不想在当今的网络上辜负用户的期望,那么优化代码性能是一项必要的任务,但这绝非易事。您的动画性能不佳可能有多种原因,但如果您尝试使用上面列出的技巧,您将朝着避免最常见的动画性能陷阱迈进一大步,从而改善您的网站或应用程序的用户体验。
关于无卡顿 JavaScript 动画的常见问题解答 (FAQ)
“卡顿”是指用户在网站或应用程序跟不上刷新率时看到的任何卡顿、抖动或简单的停顿。在 JavaScript 动画中,当帧速率低于标准的每秒 60 帧时,可能会发生卡顿。这会导致动画不那么流畅和视觉上不那么吸引人,这会对用户体验产生负面影响。
确保 JavaScript 动画流畅涉及优化代码以保持稳定的每秒 60 帧。这可以通过使用 requestAnimationFrame
方法来实现,该方法允许浏览器优化动画。您还可以对简单的动画使用 CSS 过渡或动画,因为它们通常比 JavaScript 更高效。此外,通过将 DOM 读写操作一起批处理来避免布局抖动。
requestAnimationFrame
在 JavaScript 动画中的作用是什么?JavaScript 中的 requestAnimationFrame
方法是创建流畅动画的关键工具。它告诉浏览器您希望执行动画,并请求浏览器在下次重绘之前调用指定函数来更新动画。此方法允许浏览器优化动画,从而实现更流畅、更高效的动画。
CSS 过渡和动画可能比 JavaScript 更高效,因为它们由浏览器的合成器线程处理,与主 JavaScript 线程分开。这意味着即使主线程忙于其他任务,它们也可以顺利运行。此外,某些属性可以在 CSS 中进行动画处理而不会导致重绘,这使得它们特别高效。
布局抖动是指 JavaScript 反复读取和写入 DOM,导致浏览器多次重新计算布局,从而导致动画低效、卡顿。这可以通过将 DOM 读写操作一起批处理来避免。例如,您可以先进行所有读取操作,然后再进行所有写入操作,而不是交错读取和写入操作。
will-change
属性优化 JavaScript 动画? CSS 中的 will-change
属性允许您提前告知浏览器您可能要对元素进行哪些类型的更改,以便它可以在需要之前设置适当的优化。这可以显着提高动画的性能。但是,应该谨慎使用,因为过度使用会导致浏览器花费太多时间进行优化。
transform
和 opacity
属性在 JavaScript 动画中的意义是什么? CSS 中的 transform
和 opacity
属性对于动画来说特别高效。这是因为对这些属性的更改可以由浏览器的合成器线程处理,而无需布局或绘制。这意味着即使主 JavaScript 线程繁忙,它们也可以顺利运行。
JavaScript 中的 Web Workers 允许您在后台运行脚本,与主执行线程分开。这意味着它们可以处理计算密集型任务,而不会阻塞主线程并导致卡顿。但是,它们有一些限制,例如无法访问 DOM 或某些 Web API。
“非主线程”动画是指在与主 JavaScript 线程分开的单独线程上运行动画。这可以显着提高动画的性能,因为它允许它们即使在主线程繁忙时也能顺利运行。这可以通过使用 CSS 动画、Web Workers 或 Web Animations API 来实现。
Web Animations API 提供了一种使用 JavaScript 创建动画的方法,其性能与 CSS 动画一样高效。它允许您直接从 JavaScript 控制和操作动画,为您提供比 CSS 动画更大的灵活性。但是,它仍然是一项实验性技术,并非所有浏览器都完全支持。
以上是7个无垃圾JavaScript动画的性能提示的详细内容。更多信息请关注PHP中文网其他相关文章!