背景
- 现在App,为了能更加吸引用户,总是会加入很酷炫的动画以及在列表中插入大量规格不一的图片,这么做可能会对页面流畅度造成一定的影响,给用户最直观的感受是APP变卡了,因此从测试的角度,了解一些页面显示的原理及测试工具的使用是很有必要的。
- 一般测页面流畅度会从两方面入手:页面过渡重绘 和 页面帧率测试,接下来我们围绕这两种情况进行介绍。
过渡重绘(overdraw)
概念
- android系统绘制屏幕的时候,先画父view,然后子view,再是更深的子view等等。这会导致所有的view都被绘制到了屏幕上并且view是垂直摆放的(对我们可见的是子view,它下面是父view,以此类推),因此有些父View必然是不可见的,如果他们也绘制,我们就认为发生了过渡重绘。例如:一个白色背景的窗口,在它上面有一个按钮。当系统绘制按钮时,要绘制在已存在的白色背景上。
- 因为过渡重绘,不可见页面的绘制必然会占用可见页面绘制的时间和资源,所以会对页面流畅度造成影响。
- Google给我们提供了工具来检测并快速定位过渡重绘:开发者选项——调试GPU过度绘制 选择【显示过度绘制区域】。
工具
- 勾选【显示过度绘制区域】后在屏幕上会呈现出不同的颜色,如下图所示:
没有颜色(白色): 意味着没有overdraw。像素只画了一次。
蓝色: 意味着overdraw 1倍。像素绘制了两次。(因为overdraw时,屏幕上同一位置像素点两个view都需要绘制)
绿色: 意味着overdraw 2倍。像素绘制了三次。
浅红: 意味着overdraw 3倍。像素绘制了四次。
暗红: 意味着overdraw 4倍。像素绘制了五次或者更多。
我们期望的情况是:
- 页面尽量是没有overdraw,即白色。(但根据经验,这比较难达到)。
- 页面如果大部分是蓝色区域或者绿色区域,也是可以接受的。
- 页面浅红色的区域不能超过 1/3(通过估算),需要排查下原因,看能否优化成白色、蓝色或者绿色。
- 页面不能出现深红色的区域。
问题排查
- 在测试过程中,发现问题,最好能自己分析下错误的可能原因,即使自己没有找到问题的根本原因,但是也可以将自己发现的星星点点的可能原因在提bug的时候作为描述,告诉开发,这样可以提高问题被解决的效率,一定程度上提升了工作效率。
碰到过渡重绘的问题,可以从以下几个思路来分析问题:
页面层级太多
我们可以使用AndroidStudio monitor 【Layout Inspecter】工具(最好用最新版,记得之前的版本好像还没集成Layout Inspecter),如下图所示:
抓取到的结果如下图所示:
上图第1部分是界面元素的构成情况,是分层展示的。可再回过头去想下上面提到的子view和父view的关系。
- 上图第2部分是我们能看到的界面的样子,鼠标在上面移动,图中第1和3部分也会跟着改变值。
上图第3部分是我们在第2部分选中view的一些属性值。比如我们写UI自动化时,可以从这里查看坐标或者元素id。
我截取了我认为有问题的元素,如下图所示:
!这个页面,三个item都是淡红色的,查看他们布局,我觉得用红线圈中的第二个LinearLayout可以考虑去掉,直接用RelativeLayout来实现,这样可以节省一层。
- 不过对布局问题的排查,需要一些Android界面的基础知识,但也不难,大家可以熟悉常见的几种布局即可。RelativeLayout、LinearLayout、FrameLayout。
去掉View没必要的背景色
- 这种问题也比较常见,开发在写布局时,经常先加个背景,方便调整界面,但是完成之后,背景可能被其他的View覆盖,就忘记去掉。
- 不过这个需要有布局文件才能去查看,可以问开发要一份代码,便于分析问题。
- 但是如果没有开发代码,也可以通过 apktool 命令来反编译apk的资源文件,也是可以拿到布局文件的。(不过现在有的公司已经将资源文件也处理了,比如360,但大部分的还是可以的)
其他
- 从开发的角度,还有其他优化方案,不过我们从测试的角度,能分析到这个程度已经可以了,循序渐进,慢慢再去挖掘更多的解决方案。
FPS(页面帧率)
概念
60fps VS 16ms VS 60HZ
- 60HZ是屏幕的刷新频率,即1s内,屏幕被刷新来展示数据的次数。
- 60fps是系统1s内绘制的图像帧的数目,有一些对比数据,让我们更好的理解fps, 书本快速翻页(小时候看的那种小人书)是12fps, 电影胶片的帧率是24fps。30fps已经能够展示相对流畅的画面,而60fps能够将画面展示的更加逼真和绚丽。不过大于60fps,对于人类的眼睛已经没有什么区别了,但fps越高,硬件成本会提高,所以Google将帧率的标准定为60(页面流畅的标准,理论上小于这个值,页面会有卡顿感)。不过有人肯定会有疑问,为啥电影用24fps就够了,那是因为电影胶片的一帧带有一些方向及动态元素,而手机上的一帧就是静态的一帧(之前其实尝试过高帧电影,但效果不理想,现在还在不断尝试)。
- 16ms是系统绘制一帧的时间,计算方法 = 1s / 60 fps 约等于16ms。
工具
AndroidStudio测试工具介绍
最新的AndroidStudio monitor已经集成了GPU测试工具,如下图所示:
!图中 1 是个【Launch in GFX trace mode】,可以用来trace 图形加载过程中每一帧的绘制过程,这个非常有用,可以很准备的查看每一帧都绘制了什么。但需要一些gl绘制命令的知识,目前我也没搞太明白。研究中。
- 图中2 是四种色值(因为我用的5.x的手机,6.x的设备有9种色值,将绘制的过程更加的细化),我这里就介绍下四种色值的情况,对于6.x设备的情况,大家可以自己查一下去了解:
- 蓝色(draw)代表CPU buildDisplayList的时间,换句话就是View执行onDraw方法的时间,如果蓝色占比较多,表示View比较复杂,造成onDraw耗时。
- 紫色(prepare)是5.x系统新增的,因为从5.x新增了Render Thread 专门用来渲染view(在这个过程中,UI thread 可以用来去处理之后的帧), 紫色表示CPU 中 UI thread 往Render Thread写数据的时间。紫色较多,表示需要传递的数据太多,还是反映View复杂。
- 红色(Process)表示drawDisplayList的时间,即执行前面创建的DisplayList,转换成OpenGL命令,所以DisplayList越多,那么这个过程耗时就越多,换句话说是界面上元素较多且元素的种类也多。这里可以研究下纹理的概念。
- 橙色(Execute)发送OpenGL命令到GPU。这个阶段是一个阻塞调用,因为CPU在这里只会发送一个含有一些OpenGL命令的缓冲区给GPU,并且等待GPU返回空的缓冲区以便再次传递下一帧的OpenGL命令。而这些缓冲区的总量是一定的,如果GPU太过于繁忙,那么CPU则会去等待下一个空缓冲区。所以,如果我们看到这一阶段耗时比较长,那可能是因为GPU过于繁忙的绘制UI,而造成这个的原因则可能是在短时间内绘制了过于复杂的view。
- x轴代表测试的时间。
- y轴代表的一帧绘制的时间。
- 此外,和X轴平行的还有一根绿线和红线。绿线表示的是60fps,红线表示的是30fps。
Android手机上测试工具
此外Android手机上也有GPU调试工具,在【开发者选项】—— 【GPU呈现模式分析】 选择【在屏幕上显示为条形图】,这样在手机上就能看到展示了,如下图所示:
它的色值代表的含义和AndroidStudio工具的是一样的。
- 上面提到的两种工具都可以,根据自己的需要选择。
其他工具
- 腾讯的GT,腾讯提出来页面流畅度的概念,认为fps并不能代表页面是否流畅的标准,因为在不滑动的时候,fps为0,但并不能说页面不流畅,所以fps也并不是越小页面越不流畅。它们认为1s内有多少vsync,才能代表页面是否流畅,详细介绍可参考如何量化Android应用的“卡”?—流畅度原理&定义篇
- 因为我觉得测fps时,我们一般会在不断滑动和操作页面,理论上可排除静止时fps为0的情况,我们暂时还推荐用AndroidStudio的工具。不过我们要知道有这么回事。
问题排查
- 帧率问题排查相对CPU、Memory等,略复杂,很多时候需要多种工具结合起来使用,并且需要对Android的一些绘制原理比较熟悉,所以这里如果不结合具体实例,可能讲不明白,后面碰到具体问题,再写一篇文章介绍。
- 一般会用到的工具,【traceView】【systrace】【OpenGL Trace(和上面提到的AndroidStudio GPU monitor中的GFX trace类似)】。
分析问题的大致思路
这里只能先写点假如我碰到卡顿问题怎么去分析的思路:
- 首先在滑动过程中,用traceView抓一个trace,分析onDraw()方法比较耗时的操作,或者列表滑动时,是否重复的Infalate()。主要是找和View的绘制相关的方法,是否有耗时的方法。
- 如果TraceView没有找到任何问题思路,可以用DDMS中【systrace】,这个工具是抓取系统所有的CPU及其线程在做哪些操作。我们可以找到RenderThread线程,找到有丢帧的点,然后具体分析为啥丢帧(最新版的工具,会有alert,告诉用户耗时原因),结合着其他线程在做什么任务分析。不过最后还是要回归代码去查看具体的情况或者再回到TraceView有针对性的查看对应的方法。
- 如果上面两种工具都不行,则要用杀手锏了DDMS中的【OpenGL trace】,它记录了每一帧的绘制情况,可以查看绘制帧的过程都调用了哪些方法及其耗时。我对这个工具,用的也不多,还需要多解决问题,多分析才能熟练。
总结
- 页面流畅度,我觉得多用于列表页面(可滑动)、动画复杂页面、View比较复杂页面,对于一般的展示页面,比如设置页面(一页显示完不可滑动),帧率测试可作为参考选项。
- 测页面流畅度,尽量选择性能比较差的手机,因为性能差的手机,更容易暴露问题。
- 分析问题是个耗时且高度专注的过程。