浏览器渲染流水线解析(四)

5 非合成器动画性能分析和优化指南

前面已经我们已经把非合成器动画区分为 Blink 触发,无法由合成器运行的动画和由 Timer/RAF 驱动的 JS 动画两类,因为前者可以认为是后者的一个简化版本,所以这一章主要讨论 Timer/RAF 驱动的 JS 动画。

5.1 动画流水线

从上图可以看出非合成器动画的流水线比合成器动画更长更复杂,并且非合成器动画的后半段跟合成器动画是一致的。

  1. JavaScipt 部分是页端实现的逻辑,可能包含了计算的部分,和调用浏览器提供的 API 的部分(修改 DOM 树,CSS 属性等),最终改变了网页的内容;
  2. 网页内容被改变会导致 Blink 生成新的 MainFrame,MainFrame 包括了重排版,更新图层树,和重新记录发生变更的图层的内容,生成新的 DisplayList,等等;
  3. Blink 生成新的 MainFrame 后需要向合成器发起 Commit 的请求,合成器在 Commit 过程中根据 MainFrame 生成自身的图层树,Blink 在 Commit 的过程中保持阻塞状态,Commit 完成后再继续运行;
  4. 合成器实际上有两棵图层树,新提交的 MainFrame 生成的是 Pending 树,用于绘制 Draw 的是 Active 树,只有当 Pending 树当前可见区域部分的分块全部完成 Rasterize 后,才会进入 Active 步骤,在 Active 的过程中,Pending 树相对于 Active 树的变更部分才会被同步到 Active 树;
  5. Active 后,合成器会向 UI 线程的窗口管理器发起重绘请求,窗口管理器会在下一个 VSync 的时候开始绘制新的一帧,后面的流程就跟合成器动画是一样的了;

上述流程的一些关键点是:

  1. 在合成器动画中,分块没有完成光栅化,出现空白是被允许的,这样浏览器可以更好地保证合成器动画的帧率,但是在非合成器动画中出现空白是不被允许的,因为新的 MainFrame 常常会带来大面积的变更,如果允许空白的话可能会出现非常不好的视觉效果。这样就导致合成器需要使用两棵图层树来构建一个类似双缓冲的机制,只有当 Pending 树在后台完成可见区域的光栅化时才被允许同步到 Active 树;
  2. 在非合成器动画过程中,Main Frame N,Main Frame N Active;Compositor Frame N,GL Frame N 这四个 Block 基本上可以认为是可以并发运行的(唯一会阻塞的环节是 Commit,不过 Commit 耗时一般不长),理论上我们要实现 60 帧的非合成器动画,只需要保证其中每个 Block 的耗时总和小于 16.7 毫秒即可。当然实际的状况下,在移动设备上很难实现这么多线程完全并发运行,加上过多线程带来的互相通讯的开销,使得每个 Block 的最大允许耗时实际上是小于 16.7 毫秒的;

5.2 动画耗时分析和优化指南

  1. JavaScipt 的耗时是由页端自己的逻辑决定的,一般超过 10 毫秒就基本上很难实现 60 帧的非合成器动画了;
  2. MainFrame 的耗时主要取决于网页 DOM 树,图层树的复杂程度和变化程度,在变更很小,比如只有几个元素的内容发生变化,图层树不变的情况下,一般耗时都是在 3 ~ 5 毫秒左右,如果变更很大,几十甚至几百都是有可能的;
  3. Commit 的耗时主要取决于图层树的复杂程度,一般耗时都很短,大概 2 ~ 3 毫秒上下;
  4. Rasterize 的耗时范围变化极大,取决于网页内容的复杂程度和新 MainFrame 在当前可见区域内网页内容发生变化的总面积,另外图片解码也发生在这个阶段,而图片解码也是光栅化耗时最多的一个环节,光栅化的耗时从几毫秒到几百毫秒都有可能(图片在第一次被光栅化时被解码,一直在可见区域内的图片不会被反复重解码);
  5. Active 跟 Commit 的耗时类似,主要取决于图层树的复杂程度,一般耗时很短,大概 2 ~ 3 毫秒上下;

总的来说对非合成器动画性能影响最大的通常是 JavaScript 和 Rasterize,要实现高性能的非合成器动画,页端需要很小心地控制 JavaScript 部分的耗时,并避免在每一帧中引入大面积的网页内容变化和大幅度的图层结构变化。另外非合成器动画的后半段就是合成器动画,所以对合成器动画的性能优化要求也同样适应于非合成器动画。

另外对于 WebGL 来说,当在 JavaScript 里面调用 WebGL API 时,这些命令只是被 Chrome 缓存起来,并不会在 Renderer 线程调用真正的 GL API,所以 WebGL API 在 JavaScript 部分的耗时只是一个 JS Binding 调用的 Overhead,最终绘制 WebGL 内容的 GPU 耗时实际上是被包含在最后的 GPU 的步骤里面。但是在移动平台上一个 JS Binding 调用的 Overhead 是相当高的,大概在 0.01 毫秒这个范围,所以每一帧超过 1000 个 WebGL API 调用的 WebGL 游戏,性能阻塞的瓶颈有很大概率会出现在 JavaScript 也就是 CPU 上,而不是 GPU。

时间: 2024-08-03 07:58:10

浏览器渲染流水线解析(四)的相关文章

浏览器渲染流水线解析与网页动画性能优化

若干年前,我写过一篇介绍浏览器渲染流水线的文章 - How Rendering Work (in WebKit and Blink),这篇文章,一来部分内容已经过时,二来缺少一个全局视角来对流水线整体进行分析,所以打算重新写一篇新的文章,从一个更高抽象层次和高度简化的方式对浏览器的渲染流水线进行解析,能让大部分页端同学都能够看的明白,并以此作为指引来分析和优化页面的渲染/动画性能. 有些基本概念如图层,分块,光栅化基本没有发生变化,如果读者不理解的话请参考 How Rendering Work

浏览器渲染流水线解析(一)

若干年前,我写过一篇介绍浏览器渲染流水线的文章 - How Rendering Work (in WebKit and Blink),这篇文章,一来部分内容已经过时,二来缺少一个全局视角来对流水线整体进行分析,所以打算重新写一篇新的文章,从一个更高抽象层次和高度简化的方式对浏览器的渲染流水线进行解析,能让大部分页端同学都能够看的明白,并以此作为指引来分析和优化页面的渲染/动画性能. 有些基本概念如图层,分块,光栅化基本没有发生变化,如果读者不理解的话请参考 How Rendering Work

浏览器渲染流水线解析(二)

2. 网页动画 动画可以看做是一个连续的帧序列的组合.我们把网页的动画分成两大类 -- 一类是合成器动画,一类是非合成器动画(UC 内部也将其称为内核动画,虽然这不是 Chrome 官方的术语). 合成器动画顾名思义,动画的每一帧都是由 Layer Compositor 生成并输出的,合成器自身驱动着整个动画的运行,在动画的过程中,不需要新的 Main Frame 输入: 内核动画,每一帧都是由 Blink 生成,都需要产生一个新的 Main Frame: 2.1 合成器动画 合成器动画又可以分

Chrome 渲染流水线演化的未来

前段时间我写了一篇文章浏览器渲染流水线解析与网页动画性能优化,对目前 60 左右版本的 Chrome 的渲染流水线进行解析,文末也讨论了当前渲染流水线的一些不足和未来演化的方向. 当前的渲染流水线过于复杂和冗长,特别是对于非合成器动画来说,过多的线程/进程间交互增加了不少额外开销,异步光栅化的机制也是有利于合成器动画而不利于非合成器动画.而未来的演化理应需要简化渲染流水线,减少线程/进程间交互,避免非必要的额外开销,光栅化和合成不再像现在一样泾渭分明,渲染流水线可以支持更灵活和动态自适应的图层化

【Web动画】CSS3 3D 行星运转 && 浏览器渲染原理

承接上一篇:[CSS3进阶]酷炫的3D旋转透视 . 最近入坑 Web 动画,所以把自己的学习过程记录一下分享给大家. CSS3 3D 行星运转 demo 页面请戳:Demo.(建议使用Chrome打开) 本文完整的代码,以及更多的 CSS3 效果,在我 Github 上可以看到,也希望大家可以点个 star. 嗯,可能有些人打不开 demo 或者页面乱了,贴几张效果图:(图片有点大,耐心等待一会) CSS3 3D 行星运转效果图 随机再截屏了一张: 强烈建议你点进 Demo页感受一下 CSS3

css的效率和浏览器渲染的速度

浏览器如何读取你的CSS选择器有一个很重要的原则,那就是它们从右到左读取.这意味这像 ul > li a[title="home"] 这样的选择器,a[title="home"] 将是最先被读取的. 我承认我并不经常想这个问题......我们写的css的效率是怎么样的呢,浏览器渲染的速度又如何呢? 这是应该是浏览器开发者应该关心的(页面加载更快,用户就会更愉快).Mozilla有一篇文章: about best practices . Google 当然也很关

浏览器渲染过程与性能优化

大家都知道万维网的应用层使用了 HTTP 协议,并且用浏览器作为入口访问网络上的资源.用户在使用浏览器访问一个网站时需要先通过 HTTP 协议向服务器发送请求,之后服务器返回 HTML 文件与响应信息.这时,浏览器会根据 HTML 文件来进行解析与渲染(该阶段还包括向服务器请求非内联的 CSS 文件与 JavaScript 文件或者其他资源),最终再将页面呈现在用户面前. 现在知道了网页的渲染都是由浏览器完成的,那么如果一个网站的页面加载速度太慢会导致用户体验不够友好,本文通过详解浏览器渲染页面

统一模式的WebKit浏览器渲染引擎的利弊

Opera宣布转向使用开源的WebKit引擎 在本周前几天,欧朋浏览器(Opera)宣布正在逐步关闭其独立浏览器渲染引擎(brower rendering engine)的相关开发工作,继而转向使用开源的WebKit引擎,该消息很快引起了不小的轰动. WebKit引擎支持谷歌安卓系统和苹果IOS系统的内置浏览器,在移动领域,WebKit引擎实际上已经成为了移动浏览器内核开发的标准,而且它也非常可能成为桌面浏览器的内核标准.在全球范围内Chrome浏览器已经遥遥领先以Trident排版引擎为内核的

浏览器加载、渲染和解析过程黑箱简析_javascript技巧

用 Fiddler 监控,在 IE6 下,资源下载顺序为: 很明显,下载顺序从上到下,文档流中先出现的资源先下载.在 IE8, Safari, Chrome 等浏览器下也类似. Firefox 对下载顺序做了优化:Firefox 会将 js, css 提前下载,而将图片等资源延迟到后面下载. 对于渲染,利用 Fiddler 将网速调慢,可以看到 css 下载后会马上渲染到页面,渲染和下载同步进行.js 的解析和运行,也类似. 对于 js 运行,以及页面加载相关事件的触发,特别做了测试.在 Fir