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

本文涉及的产品
全局流量管理 GTM,标准版 1个月
云解析 DNS,旗舰版 1个月
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
简介:

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

4.1 动画流水线

Compositor Animation

上图显示了合成器动画的渲染流水线示意图,根据 Android WebView 平台的实现进行绘制,其它平台可能略微不同,但对后面的性能分析,在大部分情况下影响不大

整个流水线的大概过程是:

  1. 位于 Browser 进程 UI 线程的窗口管理器接收到来自操作系统的屏幕刷新垂直同步信号(VSync),开始准备输出新的一帧,它首先给位于 Renderer 进程 Compositor 线程的 Layer Compositor 发送一个 Begin Frame 消息;
  2. Layer Compositor 接收到 Begin Frame 消息后,更新合成器内部的状态机,开始准备输出 Compositor Frame,在这个过程中的一个重要动作就是 Animate,合成器会检查当前是否有正在运行的动画,然后运行这些动画,并根据动画运行的结果改变关联图层的对应属性(比如惯性滚动动画改变图层的 Scroll Offset,Transform 动画改变图层的 Transform),Animate 的结果会发送回给 UI 线程告诉其是否有动画正在运行,需要更新窗口;
  3. 如果 UI 线程确定合成器需要更新窗口,则会发送一个 Draw 消息请求合成器输出下一帧 Compositor Frame;
  4. 合成器按下面的过程产生新的 Compositor Frame 并发送给 Display Compositor; 4.1 合成器找出在当前可见区域内显示的图层; 4.2 合成器找出这些图层在可见区域内的分块; 4.3 如果该分块已经有分配 Resource(说明此分块已经完成光栅化),则产生一个 Draw Quad 的命令置入 Compositor Frame 中,如果没有则跳过;
  5. Display Compositor 接受到新的 Compositor Frame 后,对 Compositor Frame 进行 Render,将每一个 Draw Quad 命令转换成一个 GL Draw Call,然后 GPU 执行所有的 GL 指令完成最后的窗口绘制;

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

  1. Draw 的过程中,合成器不会等待可见的分块光栅化完成,这让合成器充分利用了异步光栅化的机制来提升性能,但是也会造成动画过程中可能会出现空白的分块,比如快速滚动页面有时会看到空白区域;
  2. 在合成器动画过程中,Layer Compositor 和 Display Compositor 是异步并发的,在 Display Compositor 输出 GL Frame N 的时候,Layer Compositor 已经可以开始输出下一帧 Compositor Frame N + 1;

4.2 动画耗时分析

  1. Begin Frame 的耗时一般很短,大概 1 ~ 2 毫秒左右;
  2. Draw 的耗时也不长,一般不超过 5 毫秒,耗时主要取决于网页的图层复杂度,总的来说合成器动画过程中 Compositor 线程的开销一般都不会构成性能瓶颈;
  3. Render 的耗时也不长,一般也是不超过 5 毫秒,耗时主要取决于当前可见区域内的可见分块的数量;
  4. GPU 部分的耗时比较长,耗时主要取决于当前可见区域内的可见分块的总面积,也就是绘制的总面积,一旦 Render + GPU 部分的耗时大于 16.7 毫秒,动画就会出现掉帧;

总的来说影响合成器动画性能的最关键因素就是过度绘制系数(Overdraw,可以理解为绘制的面积和可见区域面积的比例),如果网页本身存在大量图层堆叠情况,导致过度绘制系数过高,就会严重影响合成器动画的性能。经验显示,过度绘制系数比较理想的值是在 2 以内,一般建议不超过 3,这样可以保证在中低端的移动设备上也有不错的性能表现。

另外,合成器动画过程中,Compositor 和 GPU 线程是前台线程,它们虽然理论上不会被 Worker 和 Renderer 线程阻塞,但是在真实的运行场景中,移动设备的 CPU/GPU 和内存带宽等硬件资源是有限的,如果 Worker 和 Renderer 线程处于高负荷状态下,也会导致前台的 Compositor 和 GPU 线程阻塞,最终导致合成器动画掉帧。

这种现象常见于:

  1. 网页在合成器动画比如惯性滚动过程中,有大量的 JS 加载图片或者其它内容,并频繁地对 DOM 树进行操作;
  2. 网页的图层树非常复杂,并且其结构在合成器动画过程中频繁发生变化,导致大量的光栅化任务在 Worker 线程运行;

4.3 动画性能优化 Checklist

根据上述的耗时分析,我们可以给出一个页端优化合成器动画性能的简单 Checklist

  1. 检查网页的图层结构是否合理,包括深度和数量,一般来说深度在 10 以内,数量在 100 以内是比较合理的值;
  2. 检查网页的合成器动画,包括网页的惯性滚动,各种图层的淡入/淡出等动画,在动画过程中,是否同时存在大量的网络加载和 DOM 操作,网页图层结构是否保持稳定;
  3. 当网页处于任一滚动位置上时,它的当前过度绘制系数是否合理;

如何判断网页的图层结构是否稳定,一般而言,如果是位于叶子节点的图层增加或者移除,对整个图层结构影响并不大,但是如果是中间节点的图层增加或者移除,对图层结构的影响就比较大了,并且越是接近根节点,影响就越大。

现在的页端都会大量使用异步加载来优化加载性能和流量,但是容易出现导致动画掉帧的现象。要平衡好这一点意味着需要实现一个加载和关联 DOM 操作的调度器,如果检查到动画正在运行,则停止加载或者通过节流阀机制降低加载的并发数量和频率,同时可以通过事先生成相应的 DOM 节点和图层作为占位符来避免加载后的图层结构发生剧烈变化。

目录
相关文章
|
1月前
|
运维 测试技术 持续交付
部署流水线解析
部署流水线解析
25 1
|
20天前
|
缓存 网络协议 Linux
在Linux中,当用户在浏览器当中输入⼀个网站,计算机对dns解释经过那些流程?
在Linux中,当用户在浏览器当中输入⼀个网站,计算机对dns解释经过那些流程?
|
2月前
|
域名解析 Web App开发 缓存
在浏览器上输入一个网址后,发生了什么?/HTTP的工作流程/DNS域名解析过程
在浏览器上输入一个网址后,发生了什么?/HTTP的工作流程/DNS域名解析过程
|
3月前
|
域名解析 存储 缓存
HTTP请求流程概览:浏览器构建请求行含方法、URL和版本;检查缓存;解析IP与端口
【6月更文挑战第23天】 HTTP请求流程概览:浏览器构建请求行含方法、URL和版本;检查缓存;解析IP与端口;TCP连接(HTTP/1.1可能需排队);三次握手;发送请求头与体;服务器处理并返回响应;TCP连接可能关闭或保持;浏览器接收并显示响应,更新缓存。HTTP版本间有差异。
56 5
|
2月前
|
数据安全/隐私保护 iOS开发
详细步骤解析:Undetectable指纹浏览器使用IPXProxy代理IP
对于品牌来说,社交媒体已经成为寻找目标受众的丰富资源。在社交媒体平台通过评论和留言进行推广具有很高的转化率,并且推广成本较低。为了获得可观的利润,大家可能需要管理至少几个社交媒体账号,然而在一台电脑上管理多个账号会比较困难。因此使用可靠的工具成为大家的必要选择,其中Undetectable指纹浏览器和IPXProxy代理IP就是两个不错的工具。下面给大家带来Undetectable指纹浏览器配置IPXProxy代理IP的详细教程。
134 0
|
26天前
|
机器学习/深度学习 人工智能 前端开发
【人工智能】利用TensorFlow.js在浏览器中实现一个基本的情感分析系统
使用TensorFlow.js在浏览器中进行情感分析是一个非常实用的应用场景。TensorFlow.js 是一个用于在JavaScript环境中训练和部署机器学习模型的库,使得开发者能够在客户端直接运行复杂的机器学习任务。对于情感分析,我们可以使用预先训练好的模型来识别文本中的积极、消极或中性情感。
48 4
【人工智能】利用TensorFlow.js在浏览器中实现一个基本的情感分析系统
|
17天前
|
编解码 JavaScript 前端开发
JS逆向浏览器脱环境专题:事件学习和编写、DOM和BOM结构、指纹验证排查、代理自吐环境通杀环境检测、脱环境框架、脱环境插件解决
JS逆向浏览器脱环境专题:事件学习和编写、DOM和BOM结构、指纹验证排查、代理自吐环境通杀环境检测、脱环境框架、脱环境插件解决
38 1
|
1月前
|
自然语言处理 资源调度 JavaScript
JS 逆向基础篇:JS作用域和浏览器对象属性补环境
JS 逆向基础篇:JS作用域和浏览器对象属性补环境
52 1
|
28天前
|
JavaScript
js怎样控制浏览器前进、后退、页面跳转
js怎样控制浏览器前进、后退、页面跳转
44 0
|
1月前
|
JavaScript UED
js之探索浏览器对象模型
js之探索浏览器对象模型
38 0

热门文章

最新文章

推荐镜像

更多