移动APP性能评测-流畅度评测

为了提升流畅度,Google对Android系统进行了大量的优化,包括使用GPU进行硬件加速、引入VSYNC,把Dalvik换成art等。重点讲解FPS测量流畅度的不足,对测量流畅度的方法进行改进,然后介绍如何定位流畅度问题,最后总结流畅度优化方法,以及在开发过程中如何避免流畅度降低问题。简单来说就是如何更加准确测量流畅度如何定位流畅度问题如何优化流畅度问题

流畅度评测方法介绍:

1.FPS:每秒的帧数;测量流畅度的时候有时候FPS很低,但是App看起来很流畅;
2.SM(Smoothness,SM)流畅度;
3.SF(Skipped frames):丢帧;
FPS测量流畅度过程中的两个问题:
1.为什么有时候FPS很低,但是我们却不觉得APP卡顿?
2.App停止操作之后,FPS还是一直在变化,这样的情况是否会影响FPS的准确度,
系统获取FPS的原理:手机屏幕显示的内容是通过Android系统的SurfaceFlinger类把当前系统里所有进程需要显示的信息合成一帧,然后提交到屏幕进行显示,FPS就是1s内SurfaceFlinger提交到屏幕的帧数;
问题一答案:有时候FPS很低,我们却感觉不到卡顿,是因为如果我们的屏幕根本没有绘制需求,即屏幕的显示画面是静止的,这时候FPS就是0,并不是FPS越低就越卡顿;对于界面一直不停刷新的应用如视频,可以使用FPS来评价其流畅度;
问题二答案:APP停止操作之后FPS还一直变化,是因为屏幕每一帧的合成都是针对手机里所有的进程,那么即使你的app停止了绘制,手机里其他进程可能还在绘制,比如状态栏的各种消息,这回导致FPS继续变化;
所以FPS评价流畅度很多时候不准确。
Android系统显示原理简介中,我们介绍了Android系统的显示过程,可以发现在引入VSYNC信号之后,丢帧是给人卡顿感觉的元凶,所以丢帧也可以用来测量流畅度;实际上,我们很多APP中,很少需要不断绘制的场景,很多的时候是静态的。会出现这样的情况,虽然1s中VSYNC的60个loop中不是每个都是在做绘制工作,FPS比较低并不能代表这个时候不流畅,所以FPS为1并不能代表当前APP UI界面不流畅,因此1秒内VSYNC这个loop能运行多少次更加能说明当前APP的流程度;所以丢帧和SM比FPS更能代表当前APP的流畅度。
丢帧:应该在16ms完成的工作因各种原因没有做完,占了下n个16ms的时间,相当于丢了n帧。
SM:和丢帧相对,在VSYNC机制中1s内有60个loop,因为某几次工作超过了16ms(丢帧),这样loop就无法运行60次(理论最大值);流畅度越低说明当前程序越卡顿;

如何得到流畅度(SM)

Android系统从4.1(API 16)开始加入Choreographer这个类来控制同步处理输入(Input)、动画(Animation)、绘制(Draw)三个UI操作。VSync信号由SurfaceFlinger实现并定时发送。Choreographer.FrameDisplayEventReceiver收到信号后,调用onVsync方法组织消息发送到主线程处理。Choreographer主要功能是当收到VSync信号时,去调用使用通过postCallBack设置的回调函数,我们可以在使用postFrameCallBack接口注册一个回调,每当下一帧到来时都会通知我们,我们就可以直接在回到Choreographer.FrameCallback中的doFrame方法时通知我们,我们简单的去计数就可以,然后按秒做统计,就可以知道每秒执行loop的次数;关于Choreographer更详细内容可参考Android Choreographer 源码分析;所以这个loop在1秒内运行的次数便是当前APP绘制的最高能力,也就是APP的卡顿程度;在一次loop时,如果执行时间超过16.6ms,那么多于16.6ms的时间除以16.6ms,即当前APP的丢帧情况;所以以上两个指标都可以表示当前APP的卡顿程度;但是因为SM是一个连续过程,SF非连续,所以建议采用SM作为客观指标来描述APP卡顿程度;
SM能够客观衡量Android程度卡的程度
1.根据Google文档,以及Android源码,以及SM原理理论都可以证实SM数值可以客观表示APP ui卡的程度;理论基础:Android系统显示原理简介Android Choreographer 源码分析,简单来说就是SurfaceFlinger每16毫秒会发生VSYNC信号,Choreographer.FrameDisplayEventReceiver收到信号后,调用onVsync方法组织消息发送到主线程处理,最终我们可以在Choreographer.FrameCallback中的doFrame进行计数,知道每一秒loop多少次,loop次数当前APP绘制的最高能力,这样就可以知道当前APP的流畅度

private final class FrameDisplayEventReceiver extends DisplayEventReceiver        
implements Runnable {    
  public FrameDisplayEventReceiver(Looper looper) {    
    super(looper);
  }
  @Override 
  public void onVsync(long timestampNanos, int  builtInDisplayId, int frame) {
  ...     
  mTimestampNanos = timestampNanos;        
  mFrame = frame;        
  Message msg = Message.obtain(mHandler, this);        
  msg.setAsynchronous(true);
  //发送消息,在looper下一次循环时执行run方法;
  mHandler.sendMessageAtTime(msg, timestampNanos / TimeUtils.NANOS_PER_MS);    
  }    
  @Override    
  public void run() {        
    mHavePendingVsync = false;
    /*渲染下一帧,并顺序执行callBack队列里面的callback,我们可以在使用postFrameCallBack接口注册一个回调,
     每当下一帧到来时都会到Choreographer.FrameCallback中的doFrame方法时通知我们,
    这样我们就可以知道一定时间内渲染了多少帧,也可以知道一秒内loop执行了多少次*/
    doFrame(mTimestampNanos, mFrame);    
  }
}

2.根据原理制定一些测试,观察SM数据,也可以客观表示某个Android APP卡的程度;
3.SM计算公式:SM = (60* totalSeconds - totalSkippedFrames) / totalSeconds;
丢帧(SF)能够客观描述Android程序卡的程度
1.根据Google文档,以及Android源码,以及丢帧原理都可以证实SF数值同样可以客观表示APP ui卡的程度;
2.根据原理制定一些测试,观察丢帧数据,也可以客观表示某个Android APP卡的程度;
3.但是由于这项数据时不连续的,而是离散的,所以可以作为辅助数据来评价流畅度;
当把APP静止在某个界面时流畅度很高,FPS比较低,无丢帧情况下流畅度和丢帧两个数据更加接近人对卡顿的主观感受;在APP有界面比不停变化时(如视频类应用)FPS一定程度上可以客观量化卡顿的主观感受;无变化则无法反应;无论界面是否有变化,流畅度和丢帧都可以客观量化卡顿的主观感受;建议在量化人对卡顿的主观感受主要以流畅度(SM)为主,丢帧(SF)、FPS作为辅助指标;

流畅度优化流程

1.首先通过SM对流畅度进行测试评估;
2.然后从最简单的UI层入手,优化APP的UI来提升流畅度;相关内容可参考Keeping your app responsive以及Improving Layout Performance等;
3.通过lint静态扫描发现代码中存在性能的问题;然后进行优化;相关内容可以参考使用 Lint 改进您的代码
4.最后进一步深入分析APP逻辑层和IO层存在的问题;代码逻辑分析部分,Android提供了两个很好用的工具:SystraceInspect trace logs with Traceview,后续会介绍检测应用中的UI卡顿方法;

相关背景知识:

Android消息机制、Android系统显示原理、Choreographer 源码分析

参考资料:

《移动APP性能评测与优化》--第3章 怎样才能如丝般顺滑—流畅度评测
Android 显示原理简介
Android Choreographer 源码分析
腾讯Bugly的专栏--那些年我们用过的显示性能指标

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 158,736评论 4 362
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,167评论 1 291
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,442评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,902评论 0 204
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,302评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,573评论 1 216
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,847评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,562评论 0 197
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,260评论 1 241
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,531评论 2 245
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,021评论 1 258
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,367评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,016评论 3 235
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,068评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,827评论 0 194
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,610评论 2 274
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,514评论 2 269

推荐阅读更多精彩内容