Android渲染性能——过度绘制
过度绘制是我们在开发过程中,常见的一种性能问题,按照性能影响的分类,它应该属于渲染性能。那么过度绘制到底代表了什么含义呢?我们又如何能够避免过度绘制呢?
概述
过度绘制(Overdraw)描述的是屏幕上的某个像素在同一帧的时间内被绘制了多次。在多层次的UI结构里面,如果不可见的UI也在做绘制的操作,这就会导致某些像素区域被绘制了多次。这就浪费大量的 CPU 以及 GPU 资源。
首先,我们从定义来分析,这里有几个关键词:“某个像素”、“同一帧”、“绘制多次”、“多层”、“不可见UI"。那么我们其实根据这些关键词,可以分析出一些结论:
- 过度绘制是同一个像素点,被绘制了多次造成的。
- 浪费大量的 CPU 以及 GPU 资源。
- 过度绘制通常由于 UI 层次比较多,并且在同一个区域,不可见的 UI 和可见 UI 同时参与了绘制。
- UI 层次很多,不一定有过度绘制,它们之间没有必然联系。
随着 APP 的视觉效果和复杂度的提升,我们就容易陷入采用越来越多的层叠组件来实现这种视觉效果的怪圈。这很容易导致大量的性能问题,为了获得最佳的性能体验,我们必须尽可能的减少过度绘制情况的发生。
过度绘制的检测
我们可以通过 Android 的系统工具,很方便的进行过度绘制的检测。
具体可以在手机设置里面的开发者选项,打开”调试 GPU 过度绘制“(Show GPU Overdraw)的选项,在打开的选择项中,可以选择“显示过度绘制区域”,这样就可以观察 UI 界面上的过度绘制情况了。
注意:这里菜单选项的名称,根据手机厂商的不同,略有区别。
如图,过度绘制分为4个级别,分别用一种颜色来表示:
- 蓝色:代表同一个像素点多绘制了1次。
- 淡绿:代表同一个像素点多绘制了2次。
- 淡红:代表同一个像素点多绘制了3次。
- 深红:代表同一个像素点多绘制了4次以上。
我们的目标就是尽量减少红色区域,看到更多的蓝色区域。
常见场景及优化方案
过度绘制是我们开发过程中非常常见的性能问题,它会导致渲染时间变长,甚至造成丢帧、卡顿等性能问题。
那么,我们开发中场景的过度绘制有哪些场景呢?又如何进行优化呢?
接下来用一些示例来说明一下。
1. Activity 布局中的过度绘制
Activity 中设置了背景颜色,然后 Activity 中的内容也设置了背景颜色,并且完全覆盖了 Activity 的背景颜色,这时就会产生 1 次的过度绘制,并且如果内部视图非常复杂,子容器也设置了背景颜色,这样就会产生红色区域(4+次)。
解决方法:
这类问题,其实只需要把未显示的背景色设置为透明即可,当然,没必要的嵌套视图也要去掉,减少布局层级。
2. 半透明对象产生的过度绘制
如果我们的页面中,存在一些过度动画或者其他原因设置的半透明视图,这些视图虽然几乎不可见,但是也会在测量、布局、渲染阶段进行操作,由此会导致丢帧等问题,并且半透明视图增加了GPU渲染时,图层合并的开销,应该尽量避免使用。
解决方法
- 设置视图的不可显示;
- 视图未使用时,使用 ViewPager 等方式延迟初始化视图;
- 在视图使用完成后,将视图在视图树中移除。
3. ImageView 设置默认背景
当我们使用图片时,尤其是网络获取图片,首先会显示一个占位背景图,然后当图片加载完成后,显示真实图片。这时,操作不当就会产生过度绘制问题。
解决方法
在获取到真实图片后,应该把 ImageView 的 background 设置为透明即可。
以上是一些过度绘制的示例,仅供大家参考。
总结
- 过度绘制描述的是屏幕上的某个像素在同一帧的时间内被绘制了多次的问题。
- 过度绘制是同一个像素点,被绘制了多次造成的。
- 过度绘制会浪费大量的 CPU 以及 GPU 资源。
- 过度绘制通常由于 UI 层次比较多,并且在同一个区域,不可见的 UI 和可见 UI 同时参与了绘制。
- 过度绘制会造成丢帧、卡顿等性能问题。
- UI 层次很多,不一定有过度绘制,它们之间没有必然联系,但层次过度会影响测量布局等阶段,同样会造成丢帧、卡顿等性能问题。
- 我们可以在手机设置里面的开发者选项,打开”调试 GPU 过度绘制“(Show GPU Overdraw)的选项开查看过度绘制问题。
- 开发中,应该尽量避免布局背景重叠、避免由过度绘制导致的渲染性能问题。
PS:性能优化专栏:《Android性能》持续更新中……