腾讯优测是专业的移动云测试平台,涵盖自动化测试-全面兼容性测试,远程真机租用,漏洞分析等,旗下优分享不定时提供大量的移动研发及测试相关的干货~
应用UI卡顿常见原因主要在以下几个方面:
1.人为在UI线程中做轻微耗时操作,导致UI线程卡顿;
2.布局Layout过于复杂,无法在16ms内完成渲染;
3.同一时间动画执行的次数过多,导致CPU或GPU负载过重;
4.View过度绘制,导致某些像素在同一帧时间内被绘制多次,从而使CPU或GPU负载过重;
5.View频繁的触发measure、layout,导致measure、layout累计耗时过多及整个View频繁的重新渲染;
6.内存频繁触发GC过多(同一帧中频繁创建内存),导致暂时阻塞渲染操作;
7.冗余资源及逻辑等导致加载和执行缓慢;
8.臭名昭著的ANR;
一、图形优化
渲染机制
大多数用户感知到的卡顿等性能问题的最主要根源都是因为渲染性能。从设计师的角度,他们希望App能够有更多的动画,图片等时尚元素来实现流畅的用户体验。但是Android系统很有可能无法及时完成那些复杂的界面渲染操作。
渲染操作通常依赖于两个核心组件:CPU与GPU。
CPU负责包括Measure,Layout,Record,Execute的计算操作,
GPU 负责Rasterization(栅格化)、渲染等操作
Android系统每隔16ms发出VSYNC信号,触发GPU对UI进行渲染,如果每次渲染都成功,这样就能够达到流畅的画面所需要的60fps,为了能够实现60fps,这意味着程序的大多数操作都必须在16ms内完成。
如果你的某个操作花费时间是24ms,系统在得到VSYNC信号的时候就无法进行正常渲染,这样就发生了丢帧现象。那么用户在32ms内看到的会是同一帧画面。(卡顿现象)
用户容易在UI执行动画或者滑动ListView的时候感知到卡顿不流畅,是因为这里的操作相对复杂,容易发生丢帧的现象,从而感觉卡顿。有很多原因可以导致丢帧,也许是因为你的layout太过复杂,无法在16ms内完成渲染,有可能是因为你的UI上有层叠太多的绘制单元,还有可能是因为动画执行的次数过多。这些都会导致CPU或者GPU负载过重。
Why 60fps帧/秒? 为什么是16ms毫秒?
12fps大概类似手动快速翻动书籍的帧率,这明显是可以感知到不够顺滑的。
24fps使得人眼感知的是连续线性的运动,电影胶圈通常使用的帧率,
低于30fps是无法顺畅表现绚丽的画面内容的,60fps来达到想要的效果,
超过60fps是没有必要的。
开发app的性能目标就是保持60fps,这意味着每一帧你只有16ms=1000/60的时间。
VSYNC机制
通过Vsync信号来同步UI绘制和动画,使得它们可以获得一个达到60fps的固定的帧率;
为了理解App是如何进行渲染的,我们必须了解手机硬件是如何工作,那么就必须理解什么是VSYNC。
在讲解VSYNC之前,我们需要了解两个相关的概念:
Refresh Rate:代表了屏幕在一秒内刷新屏幕的次数,这取决于硬件的固定参数,例如60Hz。
Frame Rate:代表了GPU在一秒内绘制操作的帧数,例如30fps,60fps。
GPU会获取图形数据进行渲染,然后显示器硬件负责把渲染后的内容呈现到屏幕上,他们两者不停的进行协作。
不幸的是,刷新频率和帧率并不是总能够保持相同的节奏。如果发生帧率与刷新频率不一致的情况,就会容易出现Tearing的现象(画面上下两部分显示内容发生断裂现象,来自不同的两帧数据发生重叠)。
情况一:GPU Frame rate > LED Refresh rate(不常见)
在这种情况下,某些帧显示的画面内容就会与上一帧的画面相同。糟糕的事情是,帧率从超过60fps突然掉到60fps以下,这样就会发生LAG,JANK,HITCHING等卡顿掉帧的不顺滑的情况。这也是用户感受不好的原因所在。
垂直同步及二缓冲以及三缓冲
平滑的动画一般需要每秒六十帧。而帧是由像素点构成的。当屏幕绘制一帧的时候,像素点是一行一行的进行填充的。
显示屏(LCD,AMOLED或者别的什么)从图形芯片(GPU)获取每帧的数据,然后一行一行的进行绘制。理想状况下,你期望显示屏在绘制完一帧之后,图形芯片整好能提供新帧的数据。
图像撕裂的状况就发生在屏幕绘制图像到一半的时候,GPU就载入了新一帧的数据,以致你最终得到的数据帧是半个帧的新数据和半个帧的老数据。
垂直同步,用来同步的。它告知GPU在载入新帧之前,要等待屏幕绘制完成前一帧。
除了垂直同步,还有android双缓冲机制。
缓冲就是帧构建和保存的容器。
android的双缓冲机制,它可以在显示一帧的同时进行另一帧的处理。在图中,就是缓冲A和B。当显示缓冲A时,系统在缓冲B中构建新的帧。完成后,则交换缓冲。显示缓冲B,而A则被清空,继续下一帧的绘制。
当某帧的绘制时间超过16毫秒时,双缓冲的问题就暴露出来了。
我们知道,仅在收到垂直同步脉冲时,才会进行帧(缓冲)切换。之间的空白表示浪费的时间。这就是ICS的缺陷。