原文地址css
你也许早已在项目中使用上了Animations 或 Transitions(若是尚未,能够阅读CSS-Trick’s almanac 关于animations或transitions的相关文章)。你会发现你的一些运动表现流畅,而另外一些却不尽如人意,你想知道缘由?web
本文将阐述浏览器是怎样处理CSS animations 与 transitions。以期在编写代码以前,你能够经过直觉判断某一运动可否运行良好。经过这种直觉,你将能过作出浏览器亲和且用户体验流畅的设计决策。浏览器
让我深刻浏览器内部一探究竟。只有理解了它的工做用力,咱们才能作的更好。布局
现代浏览器有两个重要的执行线程。两个线程共同协做来渲染web页面。他们是:性能
主线程(The main thread)动画
排版线程(The compositor thread)spa
通常来讲,主线程负责:线程
运行JS代码设计
计算HTML元素的CSS样式3d
布局页面
将元素绘制成一副或多幅位图
将位图传给排版线程
排版线程则负责:
经过GPU,将位图绘制到屏幕上
对可见或即将可见的区域,询问主线程是否进行位图更新。
计算页面的可见区域
当滚动屏幕时,计算出即将可见的区域
当滚动时移动页面区域
主线程花费大量的时间忙于执行JS代码与绘制大型元素。主线程正在处理任务时,他将没法响应用户的输入(注:这里是广义的输入,泛指交互)。
另外一方面,排版线程保持着对用户的输入的响应。当页面改变时,排版线程会进行每秒60次的重绘。甚至在页面还不完整时。
例如,当用户滚动页面时,排版线程会询问主线程是否为新的可见区域更新位图。然而,当主线程的反馈不那么迅速时,排版线程并不会等待。他将对已有反馈的页面进行绘制并使用空白代替未反馈的部分。
上文提到排版线程经过GPU将位图绘制到屏幕上。让咱们聊一聊GPU。
GPU是现今大多数手机,平板,电脑的组成部分。它是一个至关专门化的部件,这意味着它只专一处理一些事务。
GPUs 可以快速处理:
把图形绘制到屏幕上
重复绘制位图
在不一样的区域绘制相同位图或将位图旋转,缩放。
如今咱们对浏览网页时,硬件与软件的大体行为。让咱们来看看究竟浏览器的两个线程是如何协同运做来完成一个CSS动画的。
假设咱们使用以下代码,将一个元素从100px变为200px:
div { height: 100px; transition: height 1s linear; } div:hover { height: 200px; }
两个线程将会按照下图示意的操做执行。橙色框中的操做会消耗大量时间,而蓝色框的操做运行迅速。
如图,这一过程当中有大量的黄色框,这意味着浏览器并不能流畅运行。过渡动画将会卡顿。
在每一帧的过渡动画,浏览器都将执行布局,绘制以及向GPC内存更新新的位图的操做。如咱们所知,向GPU内存加载位图是一个至关缓慢的操做。
浏览器每一帧运行不流畅的缘由在于元素的内容在持续变化。变化元素的高度意味着其子元素的形状也跟着改变,所以浏览器要进行布局。布局后,主线程要为元素重新生成位图。
所以,改变高度是一种高代价的过渡动画。那么有什么的代价比较低廉?
假设咱们将一个元素的尺寸从一半还原会正常尺寸。同时,假设使用CSS transform 属性去缩放,采用过渡完成动画,代码以下:
div { transform: scale(0.5); transition: transform 1s linear; } div:hover { transform: scale(1.0); }
让咱们看看这个过程的示意图:
此次橙色框明显减小,这意味着动画更加流畅。元素transform 变化与高度变化的动画究竟区别在哪?
经过定义,CSS transform 属性并无改变元素与相邻元素的布局,仅仅只影响了做为一个总体的元素自身(缩放,旋转整个元素或移动整个元素)。
这对于浏览器来讲是个好消息。浏览器仅须要产生元素的位图,并在动画开始时向GPU更新位图。以后,浏览器不用再作更多的布局,绘制和位图更新操做。取而代之的是,仰仗GPU专业的能力在不一样的区域绘制相同的位图,或使之旋转,缩放。
如此,是否意味着不该进行元素高度的动画?不,有时这仰赖你的设计,运动一样能运行的足够快。也许你的元素是独立的,并不会形成其它部分的重排。也许你的元素只是简单的重绘,浏览器能够快速地执行。也许你的元素很小,浏览器只要向GPU更新一个小的位图。
固然,若是你的动画使用像CSS transform同样的“廉价”属性替代像CSS height的更“昂贵”的属性,而且这不影响你的设计理念,那就这样作吧。例如,当你的设计须要一个按钮在点击时显示菜单,你须要尝试元素的transform属性来显示菜单而不是经过使用top或height属性来实现相同或类似的效果。
下面列出一些能实现快速动画的CSS属性:
CSS transform
CSS opacity
CSS filter (取决于filter的复杂程度与浏览器性能)
这个列表如今看来可能颇有限,但随着浏览器的进步,愈来愈多的属性会运动地更快。同时,只是用这个列表上的属性,你也会惊叹于仅仅经过使用这些属性的组合就能创造出大量丰富的效果。