CSS动画原理及硬件加速
一、图层
图层即层叠上下文,具体概念和应用大家可以看我之前转自张鑫旭大神博客的《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 ),实际上只有少数属性可以,比如下面的这些:
transformopacityfilter
为了避免 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动画原理及硬件加速的更多相关文章
- Vue的css动画原理
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- css和js实现硬件加速渲染自定义滚动条
听别人说用CSS的变换来实现渲染有硬件加速的效果,看到很多大网站都开始陆续使用上了,我也来说说怎么做,我这边实现的滚动条有自然滚动效果,看起来比较自然,说的再多不如直接写,让我们开始吧! 我们需要自己 ...
- vue中css动画原理
显示原理: <transition name='fade'> <div v-if='show'>hello world</div> </transition& ...
- 36纯 CSS 动画原理,在页面上表现日蚀现象
原文地址:https://segmentfault.com/a/1190000015070543 感想: 动画,背景颜色 HTML code: <div class="sky" ...
- 如何利用 CSS 动画原理,在页面上表现日蚀现象
效果预览 在线演示 按下右侧的"点击预览"按钮可以在当前页面预览,点击链接可以全屏预览. https://codepen.io/comehope/pen/OELvrK 可交互视频教 ...
- 前端每日实战:36# 视频演示如何利用 CSS 动画原理,在页面上表现日蚀现象
效果预览 按下右侧的"点击预览"按钮可以在当前页面预览,点击链接可以全屏预览. https://codepen.io/comehope/pen/OELvrK 可交互视频教程 此视频 ...
- vue css动画原理
从隐藏到显现 从显现到隐藏 <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> ...
- css实现硬件加速
原文请点击一下链接: http://blog.teamtreehouse.com/increase-your-sites-performance-with-hardware-accelerated-c ...
- CSS开启硬件加速 hardware accelerated
作者:孙志勇 微博 日期:2016年12月6日 一.时效性 所有信息都具有时效性.文章的价值,往往跟时间有很大关联.特别是技术类文章,请注意本文创建时间,如果本文过于久远,请读者酌情考量,莫要浪费时间 ...
随机推荐
- CURL模拟表单post提交及相关常用参数的使用(包括提交表单同时上传文件)
转载自:https://blog.csdn.net/freedomwjx/article/details/43278157 (注:在curl前面加上time如time curl xxx,可以在最后显示 ...
- ActiveMQ -5.9和jms-1.1源码下载
ActiveMQ-5.9和jms-1.1源码下载:见附件
- 2017-2018-1 201552326《信息安全技术》实验二——Windows口令破解
2017-2018-1 201552326<信息安全技术>实验二--Windows口令破解 姓名:刘美岑 学号:20155326 班级:1553班 日期:10.24 一.实验环境 操作系统 ...
- 【python-excel】Selenium+python自动化之读取Excel数据(xlrd)
Selenium2+python自动化之读取Excel数据(xlrd) 转载地址:http://www.cnblogs.com/lingzeng86/p/6793398.html ·········· ...
- java基础-day22
第11天 多线程 今日内容介绍 u 多线程概述 u 线程实现 u 多线程安全问题产生 & 解决方案 第1章 多线程概述 学习多线程之前,我们先要了解几个关于多线程有关的概念. A ...
- MCU_头文件编写
头文件中一般放一些重复使用的代码,如:常量.变量.宏等的定义,函数的声明.当使用#include语句引用头头文件时,相当于将头文件中的内容复制到#include处. 头文件一般形式: #ifndef ...
- Chubby是什么?
先简单的理解,以后补充: 为了解决hadoop分布式系统的一致性问题 ,有很多人提出很多protocol,其中就有有名的Paxos算法(Latex作者提出,算法需要学习), 但是Chubby并不是一个 ...
- Event Tracing For Windows
https://blogs.msdn.microsoft.com/oanapl/2009/08/04/etw-event-tracing-for-windows-what-it-is-and-usef ...
- min cost max flow算法示例
问题描述 给定g个group,n个id,n<=g.我们将为每个group分配一个id(各个group的id不同).但是每个group分配id需要付出不同的代价cost,需要求解最优的id分配方案 ...
- 静态工厂 + DbHelper
在 .NET 的学习过程中用过三种数据库:Sql Server.Access.SQLite.Sql Server 用得相对多一点点,但是,麻烦,每次用它都需要开服务,而且还费资源,更麻烦的是拷贝到一台 ...