原理分析

FPS说明

”FPS”是词组“Frames Per Second”的缩写。“Frames Per Second”在计算机图像范畴内被翻译为:“每秒传输帧数”。更确切的解释,就是“每秒中填充图像的帧数(帧/秒)“。

人眼每秒识别帧数

人脑感知画面的连贯性是有一定限制的,人眼与大脑之间的协作无法感知超过60fps的画面更新,24fps使得人眼感知的是连续线性运动,低于24fps使得感知是不够顺滑,24fps是电影胶圈通常使用的帧率,这个帧率可以支撑大部分电影画面需要表达的内容。但是低于30fps是无法顺畅表现绚丽的画面内容,此时需要使用60fps来达到想要的效果。

60fps 16ms = 1000/60hz,相当于60fps(每秒帧率)

Android系统每隔16ms就会重新绘制一次Activity,因此,我们的应用必须在16ms内完成屏幕刷新的全部逻辑操作,每一帧只能停留16ms,否则就会出现掉帧现象(也就是用户看到的卡顿现象)。

渲染原理

渲染操作一般依赖两个核心的系统组件:CPU和GPU。
CPU主要负责Measure,Layout,Record,Execute等计算操作,GPU负责Rasterization(栅格化)操作。

何为栅格化?
所谓的栅格化,就是绘制那些Button,Shape,Path,Bitmap等组件最基础的操作。它把那些组件拆分到不同的像素上进行显示,通俗点说,就是解决哪些复杂的XML布局文件和标记语言,使之转换成用户能看懂的图像,但是这不是直接转换,XML布局文件需要在CPU中首先转换为多边形或者纹理,然后再传递给GPU进行栅格化,对于栅格化,跟Opengl有关,栅格化是一个特别费时的操作。
CPU把控件进行多边形化和纹理化,然后交给GPU进行栅格化渲染。

然而每次从CPU转移到GPU是一件很麻烦的事情,因此OpenGL ES可以把哪些需要渲染的纹理Hold在GPU 内存中,下次要渲染的时候,直接进行操作。如果更新了GPU所hold的纹理内容,那么之前保存的状态就丢失了。
因此,16ms的时间主要被两件事情占用,第一件:将UI对象转换为一系列多边形和纹理;第二件:CPU传递处理数据到GPU进行栅格化,因此要缩短这两部分的时间,需要金立减少对象转换的次数以及可能发声的问题和解决方案。下图为CPU和GPU的职责工作,以及可能发生的问题和解决方案。


列名 解释
PIPELINE 管道
PROBLEM 发生的问题
TOOLS 用什么工具来解决
SOLUTION 解决方案时什么

CPU方法,最常见的性能问题是不必要的布局和失效,这些内容必须在识图层次结构中进行测量,清除并重新创建,引发这种问题通常的原因通常有两个,一个是重建显示列表的次数太多,二是花费太多时间作废视图层次并进行不必要的重绘,这两个原因在更新显示列表或者其他缓存GPU资源时资源时导致CPU工作过度。
而GPU方法,最常见的问题就是过度绘制,通常实在像素着色过程中,通过其他工具进行后期着色时浪费了GPU处理时间。因此,对UI优化时,可以重点从以下两个方向进行:
CPU产生的问题:不必要的布局和失效
GPU产生的问题:过度绘制(overdraw)

卡顿原因

1.在ui线程中做了轻微耗时操作
2.布局Layout过于复杂,CPU负载过重
3.View过度绘制,同一帧绘制多次,GPU负载过重
4.同一时间动画执行次数过多,导致CPU和GPU负载过重
5.View频繁触发measure,layout,导致整个VIew频繁重绘
6.频繁触发GC,导致暂停线程阻塞渲染操作
7.冗余资源及逻辑导致加载缓慢
8.ANR