深入探究CSS中Animations和Transitions的工作原理

所属分类: 网页制作 / CSS 阅读数: 231
收藏 0 赞 0 分享

在这篇文章中,我们将会去探究一下浏览器是如何去处理CSS Animations和CSS Transitions的,以便使你在写一些动画效果之前就可以对该动画在浏览器中运行效果有一个心理预判。有了这些预判,你就可以设计出一些在浏览器中运行流畅的动画效果,从而带来更流畅的用户体验。

浏览器的内部工作

让我们了解一些浏览器的工作原理,一探究竟。一旦我们了解了浏览器是如何工作的,我们就可以更好的去驾驭它。

现代浏览器通常拥有两个重要的执行线程,这两个线程相互配合来渲染出页面:

    主线程

    排版线程

通常情况下,主线程主要负责以下工作:

    运行JavaScript

    计算HTML元素的CSS样式

    布局页面

    把页面元素绘制成一个或多个位图

    把这些位图移交给排版线程

通常情况下,排版线程主要负责以下工作:

    通过GPU渲染位图,并显示在屏幕上

    向主线程请求更新位图的可见部分或即将可见的部分

    判断出当前页面处于可见的部分

    判断出即将通过页面滚动而可见的部分

    随着用户滚动页面来移动这些部分(译者注:可见部分的和即将可见的部分)


当长时间运行JavaScript或渲染一个很多的元素时,主线程会一直处于忙碌状态。在这期间它不会对用户的输入做出任何反应。

在另一方面,排版线程对用户输入保持着非常快的响应。当页面变化时,排版线程尝试以每秒60帧的速度去重绘页面,即便这时页面还不完整。

举例来说,当用户滚动页面时,排版线程向主线程请求更新页面新显示部分的位图,但是,如果此时主线程并不能迅速响应请求,排版线程并不会去等待响应,它会用它目前所拥有的这部分页面的内容去渲染页面,由于对应的内容还没有,所以会以白板的形式渲染出来。

GPU

我前边提到过排版线程通过GPU把位图绘制到了屏幕上。让我们快速的过一下GPU相关的东西。

GPU是一种芯片,在今天的大多数手机,平板以及电脑中都能发现它的身影。它是非常专业的,这意味着GPU在某些方面非常擅长,但是在另外一些方面去表现不好。

GPU比较擅长于:

    绘制位图到屏幕

    重复的绘制同一个位图

    在不同的位置,以不同的旋转角度,或者不同的缩放大小来绘制同一个位图。

GPU相对慢的地方:

    将位图加载到显存里。


transition: height

现在我们已经在软件层面和硬件层面对如何渲染页面有了一个粗略的认识。接下来,让我们看一下浏览器的主线程和排版线程是如何协同工作来完成一个CSS Transition的。

假设我们想要将一个元素的高度值从100px转换到200px,如下所示:
 

CSS Code复制内容到剪贴板
  1. div {   
  2.     height100px;   
  3.     transition: height 1s linear;   
  4. }   
  5.      
  6. div:hover {   
  7.     height200px;   
  8. }  

主线程和排版线程会根据下图所示时序图来完成这个Transition。注意:在橙色方框中的操作是潜在的耗时操作,蓝色方框中的操作是较快的操作。
2015628201330808.png (958×1479)

正如你所见,整个过程有很多橙色的方框,意味着浏览器有相当繁重的工作要处理,也意味着这个Transition可能会出现卡顿。

在整个Transition的每一帧中,浏览器都要去重新布局,绘制页面,并把最新的位图对象加载到GPU。我们前边了解过,把位图对象加载到GPU的内存中是个相对缓慢的操作。

浏览器之所以要在每一帧动画上处理如此繁重的工作是因为这个元素的内容一直在变化。修改一个元素的高度可能会引起其子元素也要相应的改变大小,因此浏览器必须去重新布局。重新布局后,主线程必须为该元素重新生成位图对象。

transition: transform

由此可见,对高度进行的Transition相对来说性能比较差,那有一些性能比较好的Transition吗?

假设我们想要把一个元素从一半大小缩放到实际大小,并假设我们使用CSS的transform 属性来对它进行缩放,同时使用CSS的transition属性来生成缩放的动画效果,如下所示:
 

CSS Code复制内容到剪贴板
  1. div {   
  2.     transform: scale(0.5);   
  3.     transition: transform 1s linear;   
  4. }   
  5.      
  6. div:hover {   
  7.     transform: scale(1.0);   
  8. }  

让我们看下一下这个例子的时序图:
2015628201404981.png (958×1209)

我们看到只有很少的几个橙色的方框,意味着这个动画效果可能会很流畅!那么,一个元素的transform动画效果与其高度的动画效果有什么不同呢?


根据定义,CSS的transform属性不会改变元素的布局,也不会影响到其周围的元素。它把元素当做一个整体看待——缩放整个元素、旋转整个元素或者移动整个元素。

这对浏览器来说是一个好消息!浏览器只需在动画开始的时候生成这个元素的位图对象,并把它传递给GPU。在这之后,浏览器无需再做任何重新布局,绘制页面以及传递位图对象的操作了,相反,浏览器可以利用GPU擅长的绘制的特点来快速的在不同的位置,旋转或缩放同一个位图对象。

设计决策
那么,是否这就意味这我们不要去缓动一个元素的高度?非也,一些情况下,这是你的设计效果的一部分,并且动画效果可以非常快的完成。也许动画的元素是孤立的,不会引起页面其他部分进行重新布局;也许该元素只是单纯的进行重绘,浏览器可以快速的完成;也许该元素很小,浏览器只需将很小的位图对象传递给GPU。

当然了,在不影响你设计的视觉效果的情况下,最好去缓动一个性能较好的CSS属性,如transform,而不是去缓动一个性能较差的CSS属性,如height。举例来说,假设你的设计中有一个按钮,当点击它的时候会出来一个菜单,试着去缓动菜单的transform属性来显示它而不是缓动它的top或height属性来达到类似的效果。


在动画上特别快的CSS属性包括:

    CSS transform

    CSS opacity

    CSS filter (依赖于过滤器的复杂度和浏览器)

目前这个列表是非常有限的,但是随着浏览器的进步,你将会看到越来越多的CSS属性在动画中变得越来越快。另外,不要轻视当前的列表。你可能会很惊讶你能通过组合这些属性创造出许多丰富的效果。只要有创意!

更多精彩内容其他人还在看

CSS配合JavaScript做酷的动态页面效果

  利用CSS配合JavaScript的可以做很多更酷的动态页面效果,在本教程的最后给大家简单介绍一下CSS配合JS的应用。首先,要搞清楚事件和动作的概念。在客户端脚本中,JavaScript 通过对事件进行响应来获得与用户的交互。例如,当用户单击一个按钮或者在某段文字上移动鼠标
收藏 0 赞 0 分享

WEB标准,Web前端开发工程师必备技术列表

  想要打造并拥有一流的Web产品开发团队,在团队成员基础能力上一定要下功夫。对于Web前端产品开发来说,仅仅掌握Web1.0时代简单的"网页套接"是完全不够的。我结合自己的团队配备,特此罗列了Web前端产品工程师所涉及的技能列表如下:   通过许多实际项目,
收藏 0 赞 0 分享

用CSS制作Alpha滤镜测试板

alpha滤镜给制作网页特效提供了较大的创作空间,但由于它控制参数较多,在实际应用时,为了确定一组合适的参数值,不得不反复调整修改,在编辑窗口和预览窗口来回倒腾,甚是麻烦,本文介绍了一种简单的方法。制作一个“Alpha滤镜参数测试板”,在测试板上输入参数
收藏 0 赞 0 分享

非常流行的所谓的气泡窗口

普通的Alt无法自定义风格,而Sweet Titles通过JS脚本与CSS的集合.自定义了这种伪Alt风格. 前一段时间非常流行的,就所谓的气泡窗口(鼠标移到链接处出现的). 我们这里实现的用的是Sweet Titles的插件.显示效果完全由CSS控制.. 先下载Sweet Ti
收藏 0 赞 0 分享

CSS教程:li和ul标签用法举例

LI代码的格式化: A).运用CSS格式化列表符: ul li{ list-style-type:none; } B).如果你想将列表符换成图像,则: ul li{ list-style-type:none; list-style-image: url(/blog/images/
收藏 0 赞 0 分享

CSS教程:CSS中的定位(position)

  使用CSS来定位页面内层的位置,一直是比较难以掌握的事情,很多时候,往往被绝对定位的元素,总是以浏览器的左上角为坐标原点,此时,如果浏览器的大小改变,被定义的层就会偏离设计想要的位置,让人很挠头。   其实,要想控制好层的绝对定位,只要理解CSS中关于定位
收藏 0 赞 0 分享

CSS教程:盒模型(BOX Model)

  如果想熟练掌握DIV和CSS的布局方法,首先要对盒模型有足够的了解。每个HTML元素都可以看作一个装了东西的盒子,盒子里面的内容到盒子的边框之间的距离即填充(padding),盒子本身有边框(border),而盒子边框外和其他盒子之间,还有边界(margin),如图1所示。
收藏 0 赞 0 分享

无延迟翻滚的图形与CSS混合风格按钮

  在一个具有图形背景的按钮中添加CSS风格的文本,这种建立按钮的方法结合了具有CSS翻滚(CSS rollover)标记的开发速度和效率,从而有效地提高按钮外表图像的三维效果。   相比于常规的图形按钮,这些图形/CSS混合按钮可易于建立和载入,因为你只需要为空白按钮外面
收藏 0 赞 0 分享

css里expression实现界面对象的批量控制

用过css样式我们就知道, 可以定义一批对象的class属性来指定同一个样式来统一界面. 但如何统一同类型的对象的事件? 比如:界面有无数个 <img src="**.jpg"> 如何实现鼠标经过此图片, 图片的src变成是**_over.jpg?
收藏 0 赞 0 分享

CSS教程:水平对齐(text-align)

  水平对齐(text-align),用以设定元素内文本的水平对齐方式。   1.语法   text-align具体参数如下: 语法:text-align:left|right|center|justify 说明:设定元素内文本的水平对齐方式。 参数:left:左
收藏 0 赞 0 分享
查看更多