原创:MQA-sherryshare 百度APP技术团队
前言
在系列(一)里大家了解到了流畅度监控的必要性、以及业界对流畅度评估的一些指标和方法。接下来我们会介绍系列(二),百度APP的流畅度指标选取。
百度APP流畅度指标选取
1. 不流畅场景和权重考量
实际测试发现,在百度APP网页浏览场景下,会存在两种类型的不流畅问题,分别为“抖动/掉帧”和“卡顿”。
我们按下图举指针走动的例子来说明两种问题的区别,假定我们指针理想状态下每16.6ms理想帧的时间会走一格,完整走一圈归零需要8步。
1.1 抖动/掉帧
具体帧长序列为:前两帧理想帧(16.6ms),后3帧各2个理想帧(16.6*2ms)。实际指针走动效果:0,1,1,2,2,4,4,6。上述效果给用户的感受就是先匀速前进2步,后面走一步顿一部(掉帧),在此时钟举例时给用户的感受是掉帧,在浏览网页时特别是页面滚动状态下,给用户的感觉就是页面在“抖动”。
1.2 卡顿:
具体帧长序列为:前两帧理想帧(16.6ms),后一帧长度覆盖6个理想帧(16.6*6ms),实际指针走动效果:0,1,1,1,1,1,2。上述效果给用户的感受就是先匀速前进2步,后面一直停住(卡顿),然后突然走一步。
综上,两种问题都可能影响体验,在百度APP网页浏览场景下,都是我们需要召回的不流畅问题。且两种不流畅问题总持续时长相同的情况下(如上例实际都持续不流畅了6个理想帧的时间),当下我们期望尽量得到公平的召回,以便对两类问题都能加以优化解决。
后续在具体的算法选取上我们也会遵照这个思想尽量平衡两种不流畅问题的召回,原因是一旦出现偏袒,在实际线上的大量数据累积的作用下,就会导致最终数据越来越倾向于其中一种类型的展现。
2. 卡顿判断阈值选取
上一小节中对“卡顿”和“抖动/掉帧”的说明采用了假定的场景进行说明,那么实际产品使用中,应该给帧长设定一个什么样的阈值来判断是否会出现不流畅的现象呢?
测试同学通过长期的测试经验,初步建议了30ms和70ms两个阈值:
- 30ms对应实际绘制过程中掉(≈)1帧(16.6ms*2),此时会发生轻微卡顿或抖动——1s内帧长序列为[33,33,33,…,33]时,肉眼不会看到显著的卡顿现象,在界面出现动效、或用户主动滑动时,会出现界面整体抖动现象。
- 70ms对应实际绘制过程中掉(≈)3帧(16.6ms*4),此时会发生肉眼可见的短期卡顿——1s内帧长序列为[16.6,16.6,16.6,…,70,80,90],在界面出现动效、或用户主动滑动时,最后3帧会让用户肉眼感觉到顿住又恢复的现象。
开发同学提供了可以设置一段时间内帧长的Demo,经过产品同学多轮、多人的试验结论:
- 连续5帧帧长为30ms时,能够在网页浏览的界面滑动时明确感觉到抖动。
- 单帧帧长为70ms时,能够在网页浏览的界面滑动时明确感觉到界面顿住。
因此,最终我们的监控阈值确定了30ms、70ms两个阈值。为便于称谓统一,我们没有选择通过体感的“抖动”、“轻微卡顿”、“顿住”等不同场景、不同程度的表现来进行阈值命名,而是直接定义超过30ms的为“卡顿”,超过70ms的为“大卡顿”。
选取2个阈值的原因是为了便于更进一步聚焦优化目标,当对应场景大卡顿(顿住)问题出现明显时,通过70ms阈值提取大卡顿指标进行处理;当对应场景抖动问题较明显时,通过30ms阈值提取卡顿指标进行处理。如此,结合2.1中的思想“两种不流畅问题总持续时长相同的情况下,当下我们期望尽量得到公平的召回”,我们能够做到既公平的召回,又能够进行快速分化聚焦。
注:上述的阈值选取,为百度APP同学结合经验和人工实验针对网页浏览的滑动场景设定的阈值,实际不同产品形态、不同关注点的阈值选取有所不同,更加精确或者符合你所在产品的阈值选取方式,可以参考朱少民老师《如何获得智能终端的真实质量》中“响应时延的科学研究”、“完成时延的科学研究”中的结论:
3. 流畅度指标计算方案选取——每秒折算卡顿率
排除掉系列(一)中明确说明做流畅度跟踪存在较多弊端的FPS值,我们针对其他指标进一步讨论可靠的卡顿率监控算法。
除去系列(一)中提到的SF、SM和长帧之外,我们进一步在这些变量基础上增加了一些可选的计算方法,在算法的讨论中,我们首先假定卡顿判定阈值为30ms,以便进行对应用例下结果的计算(PerfDogJank依然沿用其原有的阈值设定标准)。并且我们额外给出了以下几个定义:
- 长帧=卡顿
- 卡顿耗时=1s内长帧长度之和=1s内卡顿总时长
- 折算卡顿帧数=卡顿耗时/16.6ms
- 每秒折算卡顿率=折算卡顿数/60=卡顿耗时/16.6/60=卡顿耗时/1000
我们的算法挑选先按照1s内的帧长序列针对“抖动/掉帧”、“卡顿”两种情形进行举例对比,结果如下:
综上,参考上述表格中的对比结果,我们最终选取了“每秒折算卡顿率”(=每秒折算卡顿数/60=每秒卡顿耗时(单位ms)/1000ms)这一计算方法。
4. 按阶段计算的流畅度指标——阶段折算卡顿率
选定了“每秒折算卡顿率”这一指标后,具体到产品上如何针对这一指标进行落地呢?我们可以单纯的按秒划分,计算每一秒的“折算卡顿率”,然后整体求均值,即得到“每秒折算卡顿率”之和的均值。结合系列(一)中介绍的“监控注意事项”——“建议区分场景和阶段进行监控”,因此我们的计算方法考虑按阶段划分。例如,在百度APP搜索场景下,我们可以划分出一个“搜索结果页”的阶段,和一个“普通落地页”的阶段,甚至进一步可以更详细的划分出“滑动阶段”和“静止阶段”,以便进行针对性的监控和优化。在此,我们引入了一个定义“阶段折算卡顿率”,即当前阶段内的整体折算卡顿率结果。
在理想状态下,阶段折算卡顿率
=阶段卡顿耗时/阶段总耗时
=阶段卡顿耗时/(1000ms*阶段总秒数)
=(阶段卡顿耗时/1000ms)/阶段总秒数
=(当前阶段内每秒“卡顿耗时/1000ms”之和)/阶段总秒数
=当前阶段“每秒折算卡顿率”之和的均值
即“阶段折算卡顿率”理想状态下应等于“每秒折算卡顿率”之和的均值。
但实际上:
- 打点操作时,无法做到每阶段单位监控时长控制到完整的1s(即分别计算时分母可能不准),可能出现正负波动,有少量误差;
- 对于一秒可以达到理想状态60帧时,阶段求均值的方法下,为求平均当前秒必须上传一个0值;阶段卡顿耗时/阶段总耗时的算法下,则只需在有卡顿时才进行统计上传。
因此最终方案选定为“阶段折算卡顿率”(=阶段卡顿耗时/阶段总耗时)进行百度APP的流畅度指标统计。
参考资料
- 腾讯perfdog:PerfDog性能狗帮助文档
- 朱少民:MTSC中国互联网测试开发大会深圳站《如何获得智能终端的真实质量》