以下是 Sarah Drasner (@sarah_edo) 的客座文章。Sarah 一直在研究并 发表关于动画的演讲。我迫不及待地想让她在这里分享一些研究成果,这次重点关注 SVG 动画和您可以用来实现它的不同技术选择。
在使用多种 SVG 动画技术几个月后,我可以为您提供一个基本概述,以便您可以自行比较它们。使用每种方法都有很好的理由。希望这篇文章可以帮助您找到适合工作的正确工具。
我们将通过对功能的基本比较。然后我们将深入了解它们的执行效果。包含两个不同的基准测试。一个是来自 Chrome DevTools 时间轴记录的,另一个是从屏幕测量视觉记录。
虽然用 CSS 样式化的 HTML 元素在动画中往往表现得更好,但 SVG 具有能够绘制任何内容并同时保持分辨率无关性的优势。在基准测试中,我们专门处理 SVG 图像。
我们将比较以下 SVG 动画技术
还有无数其他我们没有涵盖的技术,包括 Snap.svg 和较旧的 Raphaël。
值得注意的是,CSS 和 SMIL 具有浏览器本身的动画功能,而 GSAP 和 Velocity 是 JavaScript 库,它们操纵一个或多个渲染层以创建动画。
高级比较
CSS
优点
- 性能良好,尤其是在硬件加速的情况下,但可能不如 DevTools 时间轴报告的那样好。我们将在后面讨论这个问题。
- 它易于集成到现有的 UI 中,因为您无需加载任何其他资源。
- CSS 非常适合小型交互,例如悬停状态。
- 有一些 不错的资源 用于更精细定制的 cubic-bezier 缓动,这使得在开发时更容易直观地看到潜在的结果。
缺点
- 存在一些向后兼容性问题。@keyframes 在 IE9 或更低版本上无法工作。
- 您只能在伪状态(例如
:hover
和:focus
)上创建用户交互;需要使用 JavaScript 来处理诸如单击交互之类的事件。 - 多个动画的链接是通过延迟完成的,这对于较简单的动画效果很好。对于更长的动画,这会使工作流程变得非常复杂。调整时间尺度很困难,尤其是在您需要操纵前几帧时。
- 物理可能很麻烦。复杂的任务(如摩擦或逐渐减小的弹跳球)充其量非常复杂,最坏情况下根本不可行。
-
基于百分比的时间比其 JavaScript 对应项更难操作,因为它增加了一层抽象。
也许您想在动画开始后 1 秒钟执行某些操作。如果 animation-duration 为 3 秒,则这是 33.33% 的关键帧,但在 animation-duration 发生变化时会完全改变。 transform-origin
对于 SVG 并不一致- 将多个变换一个接一个地堆叠并不直观,因为它 对元素的最后放置做出响应。
- 它在不同浏览器之间 没有显示一致的行为。
Velocity.js
优点
- 易于使用的语法。如果您有现有的 jQuery 动画,很容易将其更改为 Velocity,因为它具有相同的样式语法。如果您习惯于
$.animate
,那么$.velocity
也很容易使用。 - 有许多开箱即用的缓动,并且 弹簧物理 可用。为了进一步改进,还有 步进缓动,您可以在其中传递数组。
- 语法比 CSS 或 SMIL 更简洁。
- 您可以使用一行代码来交错多个动画,尤其是在使用可用的 UI 插件时。
- 比 CSS 有更深的浏览器支持。
缺点
- 性能远优于现有的 jQuery
.animate()
,但不如 CSS、SMIL 或 GSAP。 - 提供对 IE8 的向后兼容性,但不如 GSAP 的兼容性广。
GreenSock (GSAP)
优点
- 易于使用且语法最简洁。
- GSAP 的时间轴允许您轻松控制和操作顺序动画;这使得更长的动画比几乎任何其他技术都容易得多。(您可以在同一时间点设置多个补间动画,创建场景,并以不同的时间尺度向前和向后移动 - 基本上是对动画进行动画处理)。
- 自动硬件加速。性能非常出色 - 与原生渲染一样出色。
- 应用物理很简单。他们有一个 缓动可视化器 非常有用。
- 有解决方案 用于解决一些已知的
transform-origin
问题。 - 提供对 IE6 的支持。比 CSS、SMIL 或 Velocity 的支持范围更广。
- GreenSock 拥有强大的功能集。如果您需要做某事,GSAP 可能已经考虑到了。为了了解我的意思,请查看这个强大的插件页面,https://greensock.com/plugins/,其中大多数都包含在 TweenMax 版本中(但如果您担心文件大小,他们有一个精简的 TweenLite 版本)。有一些专门的功能,例如沿着路径进行动画(就像 SMIL 可以使用
<animateMotion>
做的那样),拖放交互,甚至与画布一起使用。 - 他们有一个 jQuery 插件,它将覆盖现有的 jQuery
.animate()
并提高性能,而无需额外的编码。
缺点
- 他们的代码是开源的,但在某些情况下,您可能需要商业用途的许可证。
SMIL
优点
- 具有直接的声明性语法。
- 您可以使用与编写它相同的语法来变形路径和形状,这非常直观。这对徽标或变形按钮图标等非常有用。
- 您可以沿着路径进行动画。
- 性能非常出色,在视觉显示方面可能优于 CSS、Velocity 和 GSAP。
- 存在非基于延迟的链接,例如在另一个动画结束时开始动画。
- 易于添加到现有的 SVG 语法中,无需加载外部资源。
缺点
- 有人猜测对 SMIL 的支持是否会继续。Chrome 可能将其引入 Web Animations API(以及其他所有内容),但如果这没有实现,它可能得不到很好的维护,因为它目前使用量不足。
- 链接动画相当有限。
- 目前不支持 IE。
如果 IE 浏览器支持是一个主要问题,这里有一个非常简单的细分

基准测试概述
在跨动画方法构建平衡的基准测试时,需要考虑许多因素。它需要是一个非常简单的 SVG - 我使用了一个带有描边的矩形。此外,它需要循环,以便可以观察到随着时间的推移性能的变化。基准测试代码可以在 GitHub 上找到,也可以在 CodePen 上的此集合中找到。
在使用任何技术对 SVG 进行动画处理之前,最好优化 SVG,就像优化任何其他图像一样。一些不错的选择是浏览器内的 SVG 编辑器 或基于节点的 SVGO。
这是硬件加速的 CSS 版本
查看 Pen 基准测试 SVG 动画 - CSS 硬件加速,作者是 Sarah Drasner (@sdras),网站是 CodePen。
此基准测试包含两个不同的部分:一个基于 Chrome DevTools 时间轴记录,另一个基于屏幕上的视觉记录。这种双重方法是必要的,因为 Chrome 可能无法准确地报告时间轴中的所有处理。GSAP 的 Jack Doyle 在 这段视频 中很好地展示了可能的低估问题。
由于动画效果的呈现很大程度上取决于受众对视觉显示的理解,我包含了每种动画在运行时可能出现的“卡顿”的视觉记录,以及 Chrome DevTools Timeline 的基准测试结果。卡顿是指在创建动画或滚动事件时发生的视觉卡顿现象,目标是实现丝滑流畅的动画。如果您想了解更多关于这方面的信息,JankFree 是一个很好的资源,提供了优化代码的工具和技巧。
并非所有演示都是一样的 - 硬件加速和 CPU
在这些比较中,重要的是要意识到,仅仅使用每种方法构建动画并不能说明全部情况。对于每种技术,都有方法可以硬件加速动画以提高性能。在这个演示中,每种技术都根据动画类型进行了原生加速。例如,可以通过 CSS 将元素在合成器中设置到自己的图层(例如 transform: translateZ(0)
)来优化 SMIL。但我展示了如何在 SMIL 中直接执行此操作。为了演示性能差异,我还加入了 CSS 和 SMIL 的非硬件加速示例。
所有从库中构建的代码在测试之前都经过库作者的验证和批准。
如何使用 CSS 进行硬件加速
- 将变换设置为 null,然后使用变换进行移动。
- 您将它们卸载到 GPU(图形处理单元)。大多数现代浏览器都附带硬件加速功能,但除非它们被告知需要,否则不会使用它。
- 其他 GPU 加速:
backface-visibility: hidden;
和perspective: 1000;
- 防止动画闪烁。 - 隔离您需要移动或调整的图层。
- 使用变换进行移动。
如何使用 SMIL 进行硬件加速
- 使用
<animateTransform>
而不是<animate>
并设置 x、y、z 值(z 为 0)。 - 与 CSS 类似,这将元素移动到自己的图层。使用变换进行移动比使用边距或顶部、左侧更有效,因为它不会重新绘制。
如何使用 Velocity 进行硬件加速
- 使用
translateX
和translateY
进行移动。将元素设置为translateZ: 0;
。 - 确保通过声明动画元素的变量来避免布局抖动,以防止多次查找(这里不适用,但值得一提)。
如何使用 GSAP 进行硬件加速
- 在演示中,我们将元素设置为
force3D: "true"
,但 GSAP 现在默认包含此设置。这意味着您无需使用translateZ: 0;
进行硬件加速,它已经包含在内。 - 使用 X 和 Y 移动物体比使用边距效果更好。
- TweenLite 是 GSAP 的轻量级版本,建议将其用于较小的动画。TweenMax 提供循环支持,因此我们在这里使用它。
忠告:一次硬件加速太多图层会产生反效果。每个图层都是一个映射的 GPU 纹理 - 过多的图层会很快耗尽可用资源。因此,明智地使用硬件加速非常重要。
基准测试
以下是 Timeline 基准测试的结果:(较小的条形表示性能更好。)请特别注意“绘制”,因为这是事件中最昂贵的操作。每个基准测试都运行了 5 次以确保一致性,然后取平均值。这里还包含一个硬件加速的 CSS 版本 (HA) 以及非加速版本 (naive),以说明性能受影响的程度。这些测试是在 Chrome 版本 40.0.2214.91(64 位)上运行的 - 截至文章发布日期的最新稳定版本。请注意,版本号可能会改变 Timeline 的报告结果。


重要事项
不透明度和变换的整体性能往往更好,Timeline 报告显示它们在硬件加速的 CSS 中性能“显著”更好。

由于前面提到的 CSS 动画可能低估性能的可能性,在评估时不能仅仅依靠 Timeline,还应结合视觉效果进行判断,因为受众会根据视觉效果来评价动画。
视觉基准测试
为了完整地了解情况,我还根据视觉效果进行了几个基准测试。为此,我录制了每种技术中循环的第一个完整迭代的屏幕截图,然后使用一个名为 Physmo 的工具来绘制 SVG 元素的每个移动。我绘制了变化率超过 2 帧没有视觉变化的任何时间的比较。这显示了动画看起来暂停的时间,因此显示了卡顿现象。以下是每种技术的表现

正如杰克的演示所示,优化的 CSS 在视觉显示方面并没有真正胜过其他所有技术。SMIL 的变化率最稳定,其次是 GSAP。GSAP、CSS 和 Velocity 的表现与 Timeline 报告的结果基本一致,即它们的性能差异很大。
请注意,屏幕截图技术可能会改变这里的结果。我建议您尝试我创建的演示,或者最好自己编写比较,看看这些技术的表现如何。
基准测试会因上下文而异。使用不同的参数,特别是在加载其他资源时,会影响这些结果。关于不同情况下性能的持续对话对于改进动画技术至关重要。
更复杂的动画
对于简短的动画来说,这很好,但构建更长、更复杂的动画会怎样呢?GSAP 允许您在可调节的时间轴上工作,或者使用多个时间轴 - 您可以调整所有时间轴的时间尺度、更改放置顺序,甚至进行重叠。CSS 不允许您同时重叠不同的变换,这对于非常真实的运动来说是一个大问题。如果您考虑人们如何移动,或者物体如何相互作用,很少会出现所有事件都以线性顺序进行而没有重叠的情况。
在 CSS 动画中,你可以用延迟来链接事件,但当你想要调整其中的一部分,并且它有相应的其他部分时会发生什么呢?然后你必须回溯整个构建过程,并重新计算所有后续部分的数学运算。GSAP 的时间轴为你提供了更多控制这些动画的能力。它们还允许使用诸如物理学之类的功能,这些功能对于实现逼真的动画至关重要。
SMIL 非常适合像变形 SVG 这样的动画,而其他技术都没有以同样的能力提供这种功能。然而,目前尚不清楚该规范是否会随着时间的推移而得到维护,而且由于你必须使用现有的点,因此在同时对许多分散的元素使用这种技术就没有什么意义。
CSS 非常适合页面元素的过渡效果。你在企业网站上更常看到的东西,目标不是炫耀动画,而是更小的效果来增加兴趣或强调变化。如果你需要一点交互,悬停效果和轻量级的滚动库(如 Waypoints)可以轻松实现。
像 GSAP 和 Velocity 这样的动画库非常适合在生产中使用,因为维护工作量和必要的代码量要少得多。Velocity 的性能可能不如其他库,但简单的事实是,你可以用一个词将现有的 jQuery 代码更改为更高效的代码,这真是一个巨大的优势。Velocity 还提供物理学,而 CSS 则没有。GSAP 将其提升了一个档次:你可以使用现有的 jQuery,并简单地添加 GSAP jQuery 插件。它将覆盖你现有的 jQuery,并使其更有效地执行,而无需你更改任何代码。GSAP 还具有物理学、沿路径运动,等等。
由于一些严重的性能缺陷,jQuery 本身不应该再被认为是动画事物的合适方法。
结论
使用建议
- 对于小的过渡或简单的动画,使用 CSS 动画。你不需要加载其他资源,并且悬停时的小变形可以有利于交互和用户体验。特别是在你不必使用物理学或进行大量堆叠 SVG 变换的情况下,这些变换并不总是必要的。
- 在将 SVG 彼此变形的情况下(例如,徽标),以及当被动画的对象可以回退到 IE 中的静态图像时,使用 SMIL。
- 对于现有的 jQuery 动画,使用 Velocity 可以提高性能,而无需更改大量代码。
- 对于高性能动画或包含多个场景的长尺度动画,使用 GSAP。它解决了浏览器之间 SVG 变换原点一致性的主要问题。GSAP 功能非常强大,但你可以使用更小的版本,而不需要很多花哨的功能,只加载必要的东西。
每个人都有自己的偏好,不可能完全做到客观。在选择工具时要有目的性,因为它们都有特定的权衡取舍,并且在开发环境中上下文很重要。这篇文章作为一个一般比较,帮助开发人员找到最适合他们想要完成的任务的技术。
精彩的文章,Sarah!
一些笔记
你也可以使用 JavaScript 来变形形状,因此这不是 SMIL 独有的功能。
沿路径的动画也不再是 SMIL 的优势,因为 CSS 现在有了 运动路径模块,希望它能在这年内实现。
CSS 变换在 SVG 上不是硬件加速的,至少在基于 webkit 的浏览器中不是。据我所知,Firefox 在这方面提供了更好的性能。
文章写得很好,Sarah。基准测试非常有用,也很有见地。
干杯!
谢谢,Sara!我是你作品的忠实粉丝。
首先,关于变形形状,这是真的,我在上面的帖子中做了一个修改。
CSS 运动路径模块非常有趣,你是否知道它何时可能发布,以及它是否会对 SMIL 未来对运动路径(或一般情况)的支持产生影响?
最后,在整个 SVG 元素上使用 null Z 变换似乎对时间轴基准测试有影响,我没有对 CSS 本地和 CSS HA 进行视觉比较,这可能有用。我很乐意阅读更多关于你的发现的信息,我相信你在这方面有我可能错过的宝贵信息。如果你愿意分享,那将非常有帮助!
谢谢,Sara,我非常感谢。
我上次与运动路径规范编辑 Dirk 交谈时,他说我们应该在今年开始在浏览器中看到它,但这已经是几个月前的事了,所以我希望这仍然有效。
我不确定它会如何影响 SMIL。我知道它影响了 Web 动画 API,因为用于创建沿路径运动的对象从 API 中删除,转而使用 CSS 规范。
我喜欢 SMIL,但有传言说它将从 blink 中移除,IE 也不考虑投入任何精力到它身上,Web 动画 API 优先考虑,Firefox 也有一些错误。所以我个人不会使用它,除非是简单的动画,对于我使用的图像来说不是至关重要的。
再次强调,写得很好,信息量也很大,Sarah。=)
这些信息都非常有用。谢谢,Sara!
对不同技术的精彩总结。谢谢!
Hey Sarah,非常喜欢你的总结。我想提几件事
我们不支持在 Chrome 中对 SVG 进行合成(据我所知)。例如,在你的 SMIL 演示 中,如果你转到 DevTools 并点击渲染选项卡,可以打开“合成层边框”,你会看到框没有像其他任何提升的元素一样获得橙色边框。如果你打开“绘制矩形”,你会看到它变成了浅绿色,表明它是在每一帧都被绘制的。
如果你想全面了解属性映射到布局、绘制和合成的过程,我创建了 CSS Triggers,用于所有有趣的事情。
我认为基准测试非常困难,因为如果它们很简单,它们就不会受到主线程阻塞的影响(这通常会导致动画中出现问题,这些动画不是完全基于合成器的,比如关键帧变换动画),但如果它们过于复杂,它们就会非常专注于一个用例,很难得出有意义的比较。
我真没想到 GSAP 和 Velocity 的值差异如此之大。我原本以为它们会执行大致相同的 DOM 操作,并会产生类似的样式、布局、绘制和合成方面的惩罚。
我很高兴你在这里进行了一些基准测试,我希望其他人也会这样做,不仅是对 SVG,而且是对所有事物!:)
当然,Paul。基准测试的主要目的是鼓励更多类似的测试,我经常听到和看到人们问,为什么如果你用 Javascript 编写了一些东西,它没有用 CSS 完成,反之亦然,所以我认为仔细研究不同方法的不同优势和弊端是有帮助的,因为它们都有自己的优势。
在最后一段中,我试图稍微讨论一下上下文,这是真的,无论你在自己的开发环境中使用什么,都会影响事物的性能。我们的目的是帮助人们在做出决定时更具目的性,并希望从只使用一种工作方式中跳出来。
你的 CSS Triggers 网站很棒!我今天肯定要玩一整天。感谢你的见解。
很棒的信息。我真的很想看到在其他浏览器上进行基准测试(特别是屏幕案例卡顿计算),看看是否相同的模式也适用。
在过去的一年中,Firefox 的 SVG 动画性能有了显著提高,但我不知道这是否仅仅反映了整体更快的 SVG 渲染,还是由于专门优化了声明式动画。另一方面,Safari 在性能优化方面可能落后于 Chrome 一些。
最后,一个重要的澄清
Internet Explorer 目前不支持将 CSS 动画/过渡应用于 SVG 样式属性。它们也不支持 SVG 元素的 CSS 变换。因此,即使在 IE 10 和 11 中,CSS 动画对 SVG 的支持也是非常有限的。你可以动画字体大小,但仅此而已。
Hi Amelia,
我认为在浏览器之间进行视觉基准测试是一个好主意,我可能接下来会这样做。(但如果其他人好奇并想尝试一下,信息越多越好)
关于 IE 的观点很不错,我展示的浏览器比较不是针对 SVG 的,只是针对动画技术本身,你完全是对的,这让人困惑,我会修改以澄清这一点。
感谢你的见解,我真的很喜欢你在这里的 SVG 文章。
Heyo!Velocity.js 的作者在这里。
我非常感谢像这样的全面分解,它超越了简单的推测,并真正进行了深入研究。
我还没有从工作流程的角度优化 Velocity 以用于 SVG 动画;Velocity 的 SVG 动画性能不如 GSAP 并不让我感到惊讶。Velocity 的重点一直是标准 HTML 元素,因为它的目标是极大地改善最常见的典型 UI 动画用例(而不是图形 SVG 动画)。
但是,我将大幅调整性能,因为在接下来的周末,我有一些唾手可得的低垂果实可以采摘。
很遗憾的是,这些改进不会反映在这篇文章中,但这就是生活 :-)
嗨,Julian,
感谢您对基准测试的持续反馈。我当然很乐意像之前一样在您进行改进后重新运行它们——您只需告诉我何时准备好,我就可以在文章中添加一个附录。:)
前端的基准测试将永远是一个不断变化的目标。事物会不断更新,这对我们所有人来说实际上都是一件好事。我很高兴继续这场对话,并让其他基准测试也纳入其中。
感谢您为我们社区在性能改进方面付出的所有努力。
您能针对 jQuery 的常规 animate 进行基准测试吗?
是的,这是一个很好的提议。有很多关于您可以使用这些技术中的任何一种获得的性能提升的文献,但我可以将其包含在内,只是为了展示这一点。我也会为 jQuery 写一些并更新文章。同样,如果您愿意,也可以向存储库提交拉取请求,或者分叉 Codepen 集合中的某个笔。所有代码都是开源的,因此可以对其进行改进。谢谢!
你说 GSAP 是“开源的”,但它似乎不是。在许多情况下,它是免费使用的,而在其他情况下(当您出售使用它的网站的访问权限时)则需要付费。但是这种“免费”不是开源的。
GSAP 的确是开源的,因为源代码可以免费下载,并且它在 Github 上,对所有人开放。它在几乎所有类型的使用中都是完全免费的。但我完全理解您的观点。“开源”对不同的人意味着不同的事情。GSAP 的许可模式旨在使其极易访问(即使对于大多数商业项目也是免费的),同时保护它免受大多数开源项目中最常见的杀手:停滞。我和 Carl 已经全职工作多年,支持和改进它。尽管我可能会有偏见(而且我确实有),但我认为 GSAP 的许可证是一个特性,而不是一个负债。事实胜于雄辩。不过,它并不适合所有人。您的澄清是完全有效的。感谢您提供它。
Jack,你多次提到开源项目“停滞”的陷阱,但我必须说,这种看法让我觉得是自私的。Apache、Jquery、Firefox、PHP 等等——这些停滞了吗? IE6、ActiveScript 和 Flash 这些专有产品怎么样?
您的 GSAP 产品看起来不错,但它不是开源的,至少在我所知道的任何定义中都不是。我不允许分叉代码,对吧?显然,许可证是您的选择,但我并不相信您的选择最终会使其“免受停滞”。如果您确实停滞不前(倒闭、失去兴趣、专注于某些用户不感兴趣的方向),那会让我怎么办?与其破解您的东西以防止其停滞,我不得不寻找其他东西。
很棒的文章。之前没有意识到 css 存在不足之处。
为什么你不再次介绍 snap.svg?它就像最大的参与者之一,太重要了,不能被遗漏。
嗨,Hawk Phil,
Snap.svg 确实很重要。到目前为止,我还没有对它进行过足够深入的研究,所以暂时还没有对它得出结论。我可能会在接下来的几个月内重新运行不同类型的基准测试,届时会将其包含在内。但是,如果您想在本轮中添加它,您可以提交 PR 或者分叉某个笔——代码是开源的,就是为了这个原因,我很乐意对您的贡献进行测试。谢谢!