一、图层

  图层即层叠上下文,具体概念和应用大家可以看我之前转自张鑫旭大神博客的《CSS层叠上下文和层叠顺序》,这里我们简单复习一下产生层叠上下文的原因。

1.根层叠上下文
  指的是页面根元素,也就是滚动条的默认的始作俑者<html>元素。这就是为什么,绝对定位元素在left/top等值定位的时候,如果没有其他定位元素限制,会相对浏览器窗口定位的原因。

2.定位元素与传统层叠上下文
  对于包含有position:relative/position:absolute的定位元素,以及FireFox/IE浏览器(不包括Chrome等webkit内核浏览器)(目前,也就是2016年初是这样)下含有position:fixed声明的定位元素,当其z-index值不是auto的时候,会创建层叠上下文。

3.CSS3与新时代的层叠上下文

  以下情况会产生新的层叠上下文:

  • 根元素(HTML)
  • 绝对或相对定位且 z-index 值不为 auto
  • 一个伸缩项目 Flex Item,且 z-index 值不为 auto,即父元素 display: flex|inline-flex
  • 元素的 opacity 属性值小于 1
  • 元素的 transform 属性值不为 none
  • 元素的 mix-blend-mode 属性值不为 normal
  • 元素的 filter 属性值不为 normal
  • 元素的 isolation 属性值为 isolate
  • position: fixed
  • will-change 中指定了上述任意属性,即便你没有直接定义这些属性
  • 元素的 -webkit-overflow-scrolling 属性值为 touch

二、利用绝对定位+top/left实现动画

  上图数据中的绿色条纹表示的就是使用 top 和 left 实现动画时浏览器发生的 repaint 操作,从中可以看出动画帧数远低于60 帧。

  从 chrome 的开发者工具按 ESC 之后选择 “rendering” 面板,我们可以通过选中“Enable piant flashing”来进一步监测 repaint 操作。开启该选项后,页面中的 repaint 区域就会被绿色蒙版高亮显示出来。重新使用 top 和 left 的示例演示的话,你会发现包裹球的那块区域会一直闪烁绿色的蒙版。

  按照常理来说,改变元素位置会产生重排,为什么上面图中显示的全是重绘呢?原因是绝对定位会建立一个新的图层,而此图层上只有当前一个元素,多以只会重绘,而不会重排。这也告诉我们,在同一层中,元素数量少的情况下,重排性能对更好,速度会更快。

三、transform2D实现动画

  下图是使用CSS transform 检测到的数据:

  如你所见,动画演示期间并没有过多的 repaint 操作。

  那么,为什么 transform 没有触发 repaint 呢?简而言之,transform 动画由GPU控制,支持硬件加速,并不需要软件方面的渲染。

四、硬件加速原理

  浏览器接收到页面文档后,会将文档中的标记语言解析为DOM树。DOM树和CSS结合后形成浏览器构建页面的渲染树。渲染树中包含了大量的渲染元素,每一个渲染元素会被分到一个图层中,每个图层又会被加载到GPU形成渲染纹理,而图层在GPU中transform 是不会触发 repaint 的,最终这些使用 transform 的图层都会由独立的合成器进程进行处理。

  在我们的示例中,CSS transform 创建了一个新的复合图层,可以被GPU直接用来执行 transform 操作。在chrome开发者工具中开启“show layer borders”选项后,每个复合图层就会显示一条黄色的边界:

  示例中的球就处于一个独立的复合图层,移动时的变化也是独立的:

此时,你也许会问:浏览器什么时候会创建一个独立的复合图层呢?事实上一般是在以下几种情况下:

  • 3D 或者 CSS transform
  • <video> 和 <canvas> 标签
  • CSS filters
  • 元素覆盖时,比如使用了 z-index 属性

等一下,上面的示例使用的是 2D transition 而不是 3D 的 transforms 啊?这个说法没错,所以在timeline中我们可以看到:动画开始和结束的时候发生了两次 repaint 操作。

  3D 和 2D transform 的区别就在于,浏览器在页面渲染前为3D动画创建独立的复合图层,而在运行期间为2D动画创建。动画开始时,生成新的复合图层并加载为GPU的纹理用于初始化 repaint。然后由GPU的复合器操纵整个动画的执行。最后当动画结束时,再次执行 repaint 操作删除复合图层。

五、强制GPU渲染

  并不是所有的CSS属性都能触发GPU的硬件加速(图层在GPU中属性改变不会触发 repaint ),实际上只有少数属性可以,比如下面的这些:

  • transform
  • opacity
  • filter

  为了避免 2D transform 动画在开始和结束时发生的 repaint 操作,我们可以硬编码一些样式来解决这个问题:

.example1 {
transform: translateZ(0);
} .example2 {
transform: rotateZ(360deg);
}

  这段代码的作用就是让浏览器执行 3D transform。浏览器通过该样式创建了一个独立图层,图层中的动画则有GPU进行预处理并且触发了硬件加速。

  如果某一个元素的背后是一个复杂元素,那么该元素的 repaint 操作就会耗费大量的资源,此时也可以使用上面的技巧来减少性能开销。

六、使用硬件加速的问题

  使用硬件加速并不是十全十美的事情,比如:

  • 内存。如果GPU加载了大量的纹理,那么很容易就会发生内容问题,这一点在移动端浏览器上尤为明显,所以,一定要牢记不要让页面的每个元素都使用硬件加速。
  • 使用GPU渲染会影响字体的抗锯齿效果。这是因为GPU和CPU具有不同的渲染机制。即使最终硬件加速停止了,文本还是会在动画期间显示得很模糊。

七、总结

  感觉这里面逻辑很乱,在这里整理一下。首先transform和绝对定位都会产生新的图层,所以都不存在重排,图层在GPU中transform又不会引起重绘,这就是硬件加速的原理。另外,transform3D和2D的区别在于3D渲染前便会产生新的图层,而2D是在运行时产生图层,运行结束时删除图层。

注:本文在整理了南北在W3C上写的《CSS动画之硬件加速》中的知识点,并加入了自己的理解和总结

CSS动画原理及硬件加速的更多相关文章

  1. Vue的css动画原理

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  2. css和js实现硬件加速渲染自定义滚动条

    听别人说用CSS的变换来实现渲染有硬件加速的效果,看到很多大网站都开始陆续使用上了,我也来说说怎么做,我这边实现的滚动条有自然滚动效果,看起来比较自然,说的再多不如直接写,让我们开始吧! 我们需要自己 ...

  3. vue中css动画原理

    显示原理: <transition name='fade'> <div v-if='show'>hello world</div> </transition& ...

  4. 36纯 CSS 动画原理,在页面上表现日蚀现象

    原文地址:https://segmentfault.com/a/1190000015070543 感想: 动画,背景颜色 HTML code: <div class="sky" ...

  5. 如何利用 CSS 动画原理,在页面上表现日蚀现象

    效果预览 在线演示 按下右侧的"点击预览"按钮可以在当前页面预览,点击链接可以全屏预览. https://codepen.io/comehope/pen/OELvrK 可交互视频教 ...

  6. 前端每日实战:36# 视频演示如何利用 CSS 动画原理,在页面上表现日蚀现象

    效果预览 按下右侧的"点击预览"按钮可以在当前页面预览,点击链接可以全屏预览. https://codepen.io/comehope/pen/OELvrK 可交互视频教程 此视频 ...

  7. vue css动画原理

    从隐藏到显现 从显现到隐藏 <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> ...

  8. css实现硬件加速

    原文请点击一下链接: http://blog.teamtreehouse.com/increase-your-sites-performance-with-hardware-accelerated-c ...

  9. CSS开启硬件加速 hardware accelerated

    作者:孙志勇 微博 日期:2016年12月6日 一.时效性 所有信息都具有时效性.文章的价值,往往跟时间有很大关联.特别是技术类文章,请注意本文创建时间,如果本文过于久远,请读者酌情考量,莫要浪费时间 ...

随机推荐

  1. CURL模拟表单post提交及相关常用参数的使用(包括提交表单同时上传文件)

    转载自:https://blog.csdn.net/freedomwjx/article/details/43278157 (注:在curl前面加上time如time curl xxx,可以在最后显示 ...

  2. ActiveMQ -5.9和jms-1.1源码下载

    ActiveMQ-5.9和jms-1.1源码下载:见附件

  3. 2017-2018-1 201552326《信息安全技术》实验二——Windows口令破解

    2017-2018-1 201552326<信息安全技术>实验二--Windows口令破解 姓名:刘美岑 学号:20155326 班级:1553班 日期:10.24 一.实验环境 操作系统 ...

  4. 【python-excel】Selenium+python自动化之读取Excel数据(xlrd)

    Selenium2+python自动化之读取Excel数据(xlrd) 转载地址:http://www.cnblogs.com/lingzeng86/p/6793398.html ·········· ...

  5. java基础-day22

    第11天  多线程 今日内容介绍 u  多线程概述 u  线程实现 u  多线程安全问题产生 & 解决方案 第1章    多线程概述 学习多线程之前,我们先要了解几个关于多线程有关的概念. A ...

  6. MCU_头文件编写

    头文件中一般放一些重复使用的代码,如:常量.变量.宏等的定义,函数的声明.当使用#include语句引用头头文件时,相当于将头文件中的内容复制到#include处. 头文件一般形式: #ifndef  ...

  7. Chubby是什么?

    先简单的理解,以后补充: 为了解决hadoop分布式系统的一致性问题 ,有很多人提出很多protocol,其中就有有名的Paxos算法(Latex作者提出,算法需要学习), 但是Chubby并不是一个 ...

  8. Event Tracing For Windows

    https://blogs.msdn.microsoft.com/oanapl/2009/08/04/etw-event-tracing-for-windows-what-it-is-and-usef ...

  9. min cost max flow算法示例

    问题描述 给定g个group,n个id,n<=g.我们将为每个group分配一个id(各个group的id不同).但是每个group分配id需要付出不同的代价cost,需要求解最优的id分配方案 ...

  10. 静态工厂 + DbHelper

    在 .NET 的学习过程中用过三种数据库:Sql Server.Access.SQLite.Sql Server 用得相对多一点点,但是,麻烦,每次用它都需要开服务,而且还费资源,更麻烦的是拷贝到一台 ...