实用的 CSS — 动画性能对比

欢迎移步个人博客阅读:《实用的 CSS — 动画性能对比》css

前言

在现代浏览器中,渲染页面所要负责的线程主要有两个:主线程和排版线程。html

主线程

  • 运行 JScss3

  • 计算 HTML 元素的 CSS 样式web

  • 布局页面浏览器

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

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

在浏览器开始渲染页面,或者长时间执行某个 JS 时,主线程会一直在忙碌状态,此时对于用户的任何输入或是操做都不会有所响应。动画

排版线程

  • 经过 GPU 渲染位图,并显示在屏幕上spa

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

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

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

  • 随着用户滚动页面来移动这些部分

排版线程对于用户的操做保持快速的响应,广泛的效率时每秒 60 帧的速度去刷新显示。

Transtion

下面咱们在网页中实现一个元素的高度变化的动画,鼠标悬浮在元素上动画启动,直至完成:

<style>
#foo {
  height: 100px;
  width: 100px;
  background: red;
  transition: height 1s linear;
}
#foo:hover {
  height: 200px;
}
</style>
<body>
  <div id="foo"></div>
</body>

经过对上述代码的观察,让咱们来了解一下浏览器的两个线程是如何协同工做的:

图中橘黄色部分表明操做相对较慢,消耗较大;蓝色部分表明操做相对较快,消耗较小

animations-performance-transition.png

从上图咱们能够看到,浏览器的两个线程在来回地切换工做,并且橘黄色出现次数较多,这意味着浏览器须要处理至关多的工做。

对于浏览器而言,因为元素的高度一直在变化,所以这个动画的每一帧中,都须要从新布局 ——> 绘制页面 ——> 将新的位图加载到 GPU 中 ——> 显示。而其中加载到 GPU 是一个相对缓慢的操做。

同时咱们也在经过浏览器去查看元素动画的过程,实际上是由略微卡顿的现象的。

Transform

通过上面的实验,咱们对 transition 属性有了比较好的了解;同时咱们对上述动画性能也有一个了解。接着我须要在网页中实现一个元素的大小变化动画,鼠标悬浮在元素上动画启动,直至完成:

<style>
#bar {
  height: 100px;
  width: 100px;
  background: red;
  transition: transform 1s linear;
}
#bar:hover {
  transform: scale(2);
}
</style>
<body>
  <div id="bar"></div>
</body>

完成上述实验,再让咱们来看看两个线程工做的过程:

animations-performance-transform.png

由此咱们能够看到,两个线程来回切换的状况并很少,橘黄色部分出现的次数也较少,蓝色部分居绝大部分,这意味着这个动画效果相较于上面的要流畅不少。

在定义中,transform 是不会使浏览器产生从新排版的,所以 transform 不会影响本来的布局,以及周围的元素。它会将定义的元素做为一个总体进行缩放、移动或旋转等。

基于 transform 这类的特性,浏览器在渲染页面时能够节省不少没必要要的开支,例如从新布局和将位图传给 GPU 等工做,这样就使得动画更有效率。

总结

当页面须要位移动画时,咱们有两种方案:使用 position 或是 transalte,而这两种是符合上述状况的。其中 position 的位移方案与第一个符合,在动画执行过程当中会使浏览器从新渲染;另外一外 transalte 则与第二个符合,在执行动画时不会发生从新渲染。所以,在须要写动画时,咱们须要选择合适的方案,最好是选择 scale()rotate()transalte() 等,由于他们具备更好的性能。

参考

W3C: CSS Transforms
W3C: CSS Transitions
css-animations-and-transitions-performance

相关文章
相关标签/搜索