在某个 View 第一次需要被渲染时,DisplayList 会因此而被创建 。当这个 View 要显示到屏幕上时,我们会执行 GPU 的绘制指令来进行渲染 。
如果你在后续有执行类似移动这个 View 的位置等操作而需要再次渲染这个 View 时,我们就仅仅需要额外操作一次渲染指令就够了 。然而如果你修改了 View 中的某些可见组件,那么之前的 DisplayList 就无法继续使用了,我们需要回头重新创建一个 DisplayList 并且重新执行渲染指令并更新到屏幕上 。
需要注意的是:任何时候 View 中的绘制内容发生变化时,都会重新执行创建 DisplayList,渲染 DisplayList,更新到屏幕上等一系列操作 。这个流程的表现性能取决于你的 View 的复杂程度,View 的状态变化以及渲染管道的执行性能 。
文章插图
UI 组件的更新举个例子,假设某个 Button 的大小需要增大到目前的两倍,在增大 Button 大小之前,需要通过父 View 重新计算并摆放其他子 View 的位置 。修改 View 的大小会触发整个 HierarcyView 的重新计算大小的操作 。如果是修改 View 的位置则会触发 HierarchView 重新计算其他 View 的位置 。如果布局很复杂,这就会很容易导致严重的性能问题 。
垂直同步为了理解 App 是如何进行渲染的,我们必须了解手机硬件是如何工作,那么就必须理解什么是垂直同步(VSYNC) 。
在讲解 VSYNC 之前,我们需要了解两个相关的概念:
刷新率刷新率(Refresh Rate)代表了屏幕在一秒内刷新屏幕的次数,这取决于硬件的固定参数,例如 60Hz 。
帧率
帧率(Frame Rate)代表了 GPU 在一秒内绘制操作的帧数,例如 30fps,60fps 。
GPU 会获取图形数据进行渲染,然后硬件负责把渲染后的内容呈现到屏幕上,他们两者不停的进行协作 。
文章插图
GPU 渲染玩游戏的同学,尤其是大型 FPS 游戏应该都见过「垂直同步」这个选项 。因为 GPU 的生成图像的频率与显示器的刷新频率是相互独立的,所以就涉及到了一个配合的问题 。
最理想的情况是两者之间的频率是相同且协同进行工作的,在这样的理想条件下,达到了最优解 。
文章插图
GPU 帧率但实际中 GPU 的生成图像的频率是变化的,如果没有有效的技术手段进行保证,两者之间很容易出现这样的情况 。
当 GPU 还在渲染下一帧图像时,显示器却已经开始进行绘制,这样就会导致屏幕撕裂(Tear) 。这会使得屏幕的一部分显示的是前一帧的内容,而另一部分却在显示下一帧的内容 。如下图所示:
文章插图
撕裂的图像屏幕撕裂(Tear)的问题,早在 PC 游戏时代就被发现,并不停的在尝试进行解决 。其中最知名可能也是最古老的解决方案就是 VSYNC 技术 。
VSYNC 的原理简单而直观:产生屏幕撕裂的原因是 GPU 在屏幕刷新时进行了渲染,而 VSYNC 通过同步渲染/刷新时间的方式来解决这个问题 。
显示器的刷新频率为 60Hz,若此时开启 VSYNC,将控制 GPU 渲染速度在 60Hz 以内以匹配显示器刷新频率 。这也意味着,在 VSYNC 的限制下,GPU 显示性能的极限就限制为 60Hz 以内 。这样就能很好的避免图像撕裂的问题 。
通常来说,帧率超过刷新频率只是一种理想的状况,在超过 60fps 的情况下,GPU 所产生的帧数据会因为等待 VSYNC 的刷新信息而被 Hold 住,这样能够保持每次刷新都有实际的新的数据可以显示 。但是我们遇到更多的情况是帧率小于刷新频率 。
文章插图
VSYNC在这种情况下,某些帧显示的画面内容就会与上一帧的画面相同 。糟糕的事情是,帧率从超过 60fps 突然掉到 60fps 以下,这样就会发生 LAG、JANK、HITCHING 等卡顿掉帧的不顺滑的情况 。这也是用户感受不好的原因所在 。
渲染性能大多数用户感知到的卡顿等性能问题的最主要根源都是因为渲染性能(Rendering Performance) 。
从设计师的角度,他们希望 App 能够有更多的动画,图片等时尚元素来实现流畅的用户体验 。但是 Android 系统很有可能无法及时完成那些复杂的界面渲染操作 。
Android 系统每隔 16ms 发出 VSYNC 信号,触发对 UI 进行渲染,如果每次渲染都成功,这样就能够达到流畅的画面所需要的 60fps,为了能够实现 60fps,这意味着程序的大多数操作都必须在 16ms 内完成 。
推荐阅读
- android6.0系统Healthd深入分析
- win10下搭建flutter android应用开发环境
- Android曝重大安全漏洞:允许攻击者录制视频、监听通话
- 如何在 Linux 中找出内存消耗最大的进程
- 深入理解 Android 9.0 Crash 机制 读懂底层原理 看清表面逻辑
- 几款实用的Android Studio 插件给你推荐一下
- Android Studio Debug 的 9 个小技巧
- android Flutter 工程结构和资源文件分辨率相关的图片文件放哪儿
- Android开发者,是时候了解LeakCanary了
- 11个促进Android应用开发的工具