最近入坑 Web 动画,所以把自己的学习过程记录一下分享给大家。
CSS3 3D 行星运转 demo 页面请戳:Demo。(建议使用Chrome打开)
本文完整的代码,以及更多的 CSS3 效果,在我 Github 上可以看到,也希望大家可以点个 star。
嗯,可能有些人打不开 demo 或者页面乱了,贴几张效果图:(图片有点大,耐心等待一会)
CSS3 3D 行星运转效果图
随机再截屏了一张:
强烈建议你点进 Demo 页感受一下 CSS3 3D 的魅力,图片能展现的东西毕竟有限。
然后,这个 CSS3 3D 行星运转动画的制作过程不再详细赘述,本篇的重点放在 Web 动画介绍及性能优化方面。详细的 CSS3 3D 可以回看上一篇博客:【CSS3进阶】酷炫的3D旋转透视。简单的思路:
1. 利用上一篇所制作的 3D 照片墙为原型,改造而来;
2. 每一个球体的制作,想了许多方法,最终使用了这种折中的方式,每一个球体本身也是一个 CSS3 3D 图形。然后在制作过程中使用 Sass 编写 CSS 可以减少很多繁琐的编写 CSS 动画的过程;
3. Demo 当中有使用 Javascript 写了一个鼠标跟随的监听事件,去掉这个事件,整个行星运动动画本身是纯 CSS 实现的。
下面将进入本文的重点,从性能优化的角度讲讲浏览器渲染展示原理,浏览器的重绘与重排,动画的性能检测优化等:
浏览器渲染展示原理 及 对web动画的影响
小标题起得有点大,我们知道,不同浏览器的内核(渲染引擎,Rendering Engine)是不一样的,例如现在最主流的 chrome 浏览器的内核是 Blink 内核(在Chrome(28及往后版本)、Opera(15及往后版本)和Yandex浏览器中使用),火狐是 Gecko,IE 是 Trident ,浏览器内核负责对网页语法的解释并渲染(显示)网页,不同浏览器内核的工作原理并不完全一致。
所以其实下面将主要讨论的是 chrome 浏览器下的渲染原理。因为 chrome 内核渲染可查证的资料较多,对于其他内核的浏览器不敢妄下定论,所以下面展开的讨论默认是针对 chrome 浏览器的。
首先,我要抛出一点结论:
使用 transform3d api 代替 transform api,强制开始 GPU 加速
这里谈到了 GPU 加速,为什么 GPU 能够加速 3D 变换?这一切又必须要从浏览器底层的渲染讲起,浏览器渲染展示网页的过程,老生常谈,面试必问,大致分为:
1. 解析HTML(HTML Parser)
2. 构建DOM树(DOM Tree)
3. 渲染树构建(Render Tree)
4. 绘制渲染树(Painting)
找到了一张很经典的图:
这个渲染过程作为一个基础知识,继续往下深入。
当页面加载并解析完毕后,它在浏览器内代表了一个大家十分熟悉的结构:DOM(Document Object Model,文档对象模型)。在浏览器渲染一个页面时,它使用了许多没有暴露给开发者的中间表现形式,其中最重要的结构便是层(layer)。
这个层就是本文重点要讨论的内容:
而在 Chrome 中,存在有不同类型的层: RenderLayer(负责 DOM 子树),GraphicsLayer(负责 RenderLayer 的子树)。接下来我们所讨论的将是 GraphicsLayer 层。
GraphicsLayer 层是作为纹理(texture)上传给 GPU 的。
这里这个纹理很重要,那么,
什么是纹理(texture)?
这里的纹理指的是 GPU 的一个术语:可以把它想象成一个从主存储器(例如 RAM)移动到图像存储器(例如 GPU 中的 VRAM)的位图图像(bitmap image)。一旦它被移动到 GPU 中,你可以将它匹配成一个网格几何体(mesh geometry),在 Chrome 中使用纹理来从 GPU 上获得大块的页面内容。通过将纹理应用到一个非常简单的矩形网格就能很容易匹配不同的位置(position)和变形(transformation),这也就是 3D CSS 的工作原理。
说起来很难懂,直接看例子,在 chrome 中,我们是可以看到上文所述的 GraphicsLayer -- 层的概念。在开发者工具中,我们进行如下选择调出 show layer borders 选项: