cherryvenus

流畅web动画的十个法则

cherryvenus · 2016-12-05翻译 · 1487阅读 原文链接

自从我们去年登陆了Gyroscope,许多人都问我有关用在我们网站上的javascript动画库。我们考虑过将此开源,但是这不是魔法真正实现的地方。

我不希望大家认为我们是依靠特殊的javascript插件来解决这些问题的。对于大部分人来说,我们只是充分利用了近来浏览器性能的提升,GPU和CSS3规格.

对于良好的动画性能没有高招,除了将大量的时间放在测试和优化。然而,过了许多年的实验和撞击浏览器性能的极限,我们发现了一系列的设计和代码准则,看上去似乎是良好动画可靠的结果。这些技术让你的页面,在现代桌面和手机浏览器上变得流畅,运行良好。最重要的是,易于维护。

对每个人来说,技术和实现方式都有所不同,但是大体上的规则对大多是情况都会有帮助。

什么是动画?

动画在互联网出现之前就已经饱经世故了,并且如果你想做好它,这会是你一生的课题。然而对于应用于互联网的动画,有一些特别的约束和挑战。

对于60帧的流畅动画,每一帧都需要在16ms内渲染!这并没有多少时间,因此为了流畅的性能,我们需要找到非常有效的方法来渲染每一帧。

一些经典的动画规则

T 在web上有一打方法做动画。比如,幻灯片是一种方法,在互联网之前就已经流行,通过轻微不同的手绘帧,在一秒内多次置换,来创造运动的视觉效果。

最近Twitter使用这种简单的方法,制作了新的爱心动画,通过切换一组雪碧图切换实现。

这个效果不能用一堆小元素单独做动画,或者做一个SVG,但是那样会产生十分不必要的复杂以及可能会不流畅。

在许多例子中,你会想用CSS transition属性来做自动动画。这个技术也同样以“补间动画”闻名,在两个不同的值之间的过渡。这个好处就是,你可以轻易地取消,而不需要建立所有的逻辑。这个对于“一劳永逸”样式的动画是理想的解决方式,就像介绍序列,等等,或者简单如悬停的交互。

延伸阅读: 你需要知道关于CSS Transitions的事

在其他例子中,关键帧为基础的CSS动画属性也许对于不间断运行的背景细节是非常理想的。举个例子,在Gyroscope logo上的戒指计划是不间断地旋转。其他受益于CSS动画语法的是齿轮速比。

因此,事不宜迟,这里有些建议能够帮助你很大程度上地提高你的动画性能……

#1

不要改变除了opacity和transform之外的参数!

即使你觉得这样ok,也不要这么做!

仅仅这一个基本的准则能帮你解决80%的问题,即使是在手机上。你可能在之前听过这个——这不是最初的主意,但是是很少被跟随。这相当于是web的“吃的健康和运动”的相同法则,这个听上去是一个好的建议,但是你可能会无视。

一旦你如此想了,你会发现这个相对简单,但是可能会是一个大跳跃,对这些习惯传统CSS属性的动画。

举个例子,如果你想让元素变小,你可以使用transform: scale(),而不是改变他的宽度。如果你想移动他,不同于用外边距或者内边距混在一起——你可以仅仅使用一个简单的transform: translateX或者transform: translateY

为什么这个是有效的?

对于人类来说,改变宽度,外边距或者其他属性,看上去不是很大的交易——因为它更简单,看上去更好——但是电脑需要做的事情和人类比起来简直是天壤之别,他要做的更加多更加槽糕。

浏览器团队花费了很大的力气在优化这些操作。Transforms真的很简单就能提高效率,并且经常能够充分利用你的图形界面,而不用重新渲染元素。

第一次载入页面的时候,你可能会抓狂——在所有的角落,使用图片,在每个元素上加上阴影,如果你觉得特别粗糙,你甚至可以加上一个动态模糊。如果这只发生一次,一些额外的毫秒时间计算并不影响。但是一旦内容重新渲染,你不会想重新计算所有的内容。

延展阅读:用translate移动元素 (Paul Irish)

#2

将内容藏在不起眼的地方

使用pointer-events:通过透明度为0来隐藏元素

这个属性也许会有浏览器兼容的问题,但是如果你只是为webkit或者其他现代浏览器做东西,这会让你的生活更美好。

过去很长一段时间,当动画需要通过jQuery的animate()处理的时候,许多渐变元素的复杂来自切换“display“属性实现的:在一个合

CSS的pointer-events属性(这已经存在了很长时间了,但是不经常用),让元素不回应任何点击和交互,就像他们不在那边一样。它可以简单地通过CSS切换开启和关闭,而不通过打断动画或者以任何方法影响渲染/可见性。

与opacity为0结合使用,他基本上和display:none是一样的效果,但是不触发新的渲染而影响性能。当隐藏元素时,我可以常常只设置opacity为0,并且关闭pointer-events,然后遗忘元素,他会自己照顾自己。

这和绝对定位的元素一起工作地特别好,因为你会十分有信心,它对页面其他的元素完全没有影响。

这也给你更多的回旋余地,因为定时并不完美——这不是世界末日,如果一个元素是可点击的或者在其他元素上遮盖一秒或者更长,或者如果这仅仅能被点一次,然后就隐藏起来了。

#3

不要同一时间所有元素都做动画

除非使用编排

一个单独的动画自己是流畅的,但是同一时间许多元素都做动画,就会扰乱他们。创建单个的流畅动画很简单——但是一个数量级的动画就很难确保性能达到满分。因此,合理地规划特别重要。

将时间分开,那么所有的元素都不在一个相同的时间开始。典型的是,2,3个可以在同一时间运行,而不需要减速,特别是如果他们在稍不同的时间开始动画。

除非你的页面上只有一个元素,不然理解编排是很重要的。这可能看上去像一个舞蹈编排,但事对于动画接口来说是同样重要的。元素需要在一个合适得位置合适的时间进入。及时他们都是分开的,他们必须感觉是设计好的的一个单元。

Google素材设计在这个主题上又很有意思的建议。这不仅仅是做事的正确方式,也是你需要考虑的事情和测试。

延伸阅读: Google素材设计 · 动机

#4

轻微地增加延迟,让编排动作变得简单_

编排动画真的十分重要,并且需要十分多的实验和测试才能找到感觉。然而,他的代码并不十分复杂。

我通常会改变父元素上的一个Class(通常是在body上),来触发一系列变化,每一个在特定的时间有自己的过度延迟。从代码观点来说,你只需要关心状态改变,并且不需要在javascript中维护一堆定时。

Gyroscope Chrome 扩展的动画

交错安排一系列元素,是最简单的编排你的元素的方法。这很强大,因为这同时看上去很好,同时也带来了珍贵的性能——记住只有一小部分元素在同一时间开始。你会将他们分开直至感觉足够流畅,但是不要分得太开,导致整体看上去太慢。足够应该是重叠,这感觉像一个不间断的流,而不是一系列独立的个体元素。

代码样例

这里有一系列简单的技巧,交错排序你的元素——特别是如果是一长串元素。如果有少于10个元素,或者有一个不可估量的数量(就像在静态页面),然后我通常在CSS指定值。这是最简单的便于维护的方法。

一个简单的SASS循环

对于很长的元素列表或者一个动态的内容,定时器可能需要通过循环每个元素动态设置。

最简单的javascript循环

这里有两个常用变量:你的基本延迟和每个元素之间的延迟。这是一个需要寻找的微妙的平衡,但是当你敲击正确的数字集,这会感觉非常好。

#5

使用全局倍数来设计慢动画

然后加速之后所有的元素

对于动画设计,定时就是一切。20%的工具是实现他们,并且其他80%是找到正确的参数&让一切同步的间距,以及感觉流畅。

特别是在编排一系列元素的时候,尝试压榨性能和页面并发性,看看所有的元素在慢动作下会让事情变得简单。

无论你是否用javascript,或者一些CSS预处理器,如Sass(我的最爱),这都需要直接做些额外的算数,和创建变量。

你必须确认尝试一些不用的速度或者定时是很方便的。比如,如果一个动画在十分之一的速度下都很卡顿,那么有可能从根本上就有问题。如果将它调至50倍速度依然流畅,那么问题就是要找到他所能达到的最快的速度。在全速之下,5毫秒的问题很难察觉,但是如果你降低了整体的速度,那么他们就会变得特别明显。

特别对于十分复杂的动画,或者解决棘手性能的瓶颈,在慢动作下查看元素的能力可能十分有用。

最主要的问题是,你想包装许多完美的细节,当它变得慢的时候,然后提高整体的速度,因此这感觉是十分棒的。这十分微妙,但是用户会察觉流畅以及细节。

这些特性只是OS X的一部分——如果你点击shift按钮来减小按钮或者一个app图标,你会看到他在慢速运行。在这一点上,当你按shift按钮的时候,我们甚至可以在Gyroscope实现激活慢动画。

#6

拍下你的UI,并且重放他们,以获取有价值的第三方关点。

有时候一个不同的关点,能帮助你看事物更透彻,并且视频是一个极佳总这件事的方法。

一些人在AE中创建视频,并且尝试将他们在网站上实现。我经常换做其他的方式,然后尝试做一个来自网站的UI好视频。

能够发表vine或者一些video,是十分高杆的。有一天,我十分激动于我做的东西,并且尝试做成视频,分享给一些小伙伴。

然而,当我再看一次的时候,我发现有一堆东西不够完美。有一个大的滞后阻碍了之后的动画,并且所以的定时器都有一些问题。这让我有些担心,我最后没有发表它而是意识到我还有许多工作要做。

当要在正式环境使用它的时候粉饰这些很容易,但是看在视频上的动画——一遍又一遍或者在一个很慢的速度——让所有的问题都变得十分明显。

他们说相机加了10磅。也许这也增加了10帧。

I 这现在也变成了我工作流中重要的一部分,查看页面慢动画视频,以及如果有任何帧让我感觉不对,就马上做些改变。要怪罪于慢浏览器很容易,但是在一些更加优化的浏览器上,测试,有可能解决了所有的问题。

一旦你在视频上捕捉滞后停顿不觉得尴尬的时候,并且感觉视频够好,能够分享了,那么页面差不多就可以准备上线了。

#7

网络活动导致滞后

你需要提前或者滞后加载大的http请求

图片是这个问题的最黑祸首们,是否一些大家伙(也许是一个大的背景)或者大量地小图片(想象50个表情符加载),或者仅仅有许多内容(一个很长的到底都有图片的页面)。

当页面第一次加载,大量的东西初始化和下载。有统计,广告和其他的第三方脚本让事情变得更糟糕。有时候,延迟所有的动画到加载完几百毫秒之后对性能有极大的帮助。

除非必要,不要过度优化,但是一个复杂的页面也许需要十分准确的延迟和内容定时,然后才能运行路畅。通常上来说,你想要在开始加载尽可能少的内容,一旦重的部分和简介动画做完之后,不断地加载页面其余的部分。

有许多数据的页面,加载所有的元素的工作量似乎是巨大的。一旦在做动画的同时开始加载真实数据,一个动画和静态页面运行地很好也许看上去是分开的。如果一些东西看上去应该工作或者有时候工作地流畅其他时间不流畅。我建议减产网络活动,确认你没有在同一时间做其他事情。

#8

不要直接绑定滚动

看上去是一个很酷的主意,但实际上不是。

在过去几年中,滚动为基础的动画很受欢迎,特别是在视差或者其他特殊效果中。是否是好设计,有待辩论,但是有一些好或者槽糕的方法去实现他们。

在这个类别中,适度的优化做些的事是将达到滚动到一定距离作为一个事件——并且仅仅运行一次。除非你真的了解你在做什么,我会建议避免这个类别,因为这很容易出问题而且真的很难维护。

更加糟糕的是,创建你自己的滚动条功能,而不是用默认的——也就是scrolljacking。请不要做么做!

这条建议对手机来说特别有用,但是也可能是用户体验的好实践。

如果你确实有一个特别的体验,你想专注在滚动或者其他特殊事件,我会建议创建一个快速原型,以确保这在花费大时间设计的时候,能够运行良好。

#9

尽早&经常在手机上测试。

大多数网站是在电脑上创建的,并且很有可能在他们创建的相同机器上运行测试。因此手机体验和动画性能经常是后知后觉的。一些技术(比如canvas)或者动画技术在手机并没有运行地这么好。

然而,如果编写&优化适当(看规则#1),一个手机体验可能会比电脑体验还要好。手机优化是一个非常棘手的课题,但是新的iPhone现在比大多数手提都要快!如果你按照之前的建议编写,你会发现你做的东西在手机上有着极佳的性能。

手机用法会是对于大多数网站都是一个非常大而且重要的部分。这看上去和极端,但是对于一整个项目,我会建议将手机从你的项目中分离出来。这不应该感觉像是一个惩罚去做手机版本,虽然经常会这样。

保持设计进步&性能加强,知道这感觉被打磨流畅已经像网站的大版本那样方便。

如果你强迫自己只用手机网站一个礼拜,你很可能就会将它优化得向大型网站一样,有着的极佳体验。经常懊恼地使用是值得的,这意味着在你的用户体验之前解决问题。

#10

在不同的设备上经常测试

屏幕大小,像素,或者设备都有着极大的暗示 . 除了手机vs桌面,有许多关键点会彻底影响性能,就像是否屏幕是“retina”屏,窗口的总像素,硬盘多老了,等等。

即使Chrome和Safari都是webkit的浏览器,有着相同的语法,他们也都有各自怪异行为。每一次chrome更新都会修复一些东西以及引入新的bug,因此你需要一直保持警觉。

当然,你不仅仅只希望创建最低水准的性能,因此找到最机智的方法来渐进添加或者移除增强功能会十分有用。

我经常在我的小Macbook和大的iMac之间切换,并且每次切换都引出了一些小问题并且做些改进——特别是依据动画性能,但是对于总体设计,信息密度,可读性,等等。

媒体查询,常常是强大的工具来处理这些不同环节样式,通过不同的高度或者宽度是最基础的媒体查询的用法。找出OS和设备的类型会很有用,因为手机性能特性和电脑很不一样。

我希望你在你的下一个项目中,会找到有用的技巧。好运!

相关文章