一、先了解几个缩写的含义:
-
- jank:卡顿次数
- bigJank:严重卡顿次数
- stutter:卡顿率=卡顿时长/总时长
- lostFrame:丢帧率=实际帧数/预期帧数
- frameInfo:帧耗时,即每一帧渲染耗
二、以 Google Vitals 的卡顿描述为准,即呈现速度缓慢和帧冻结两个维度判断:
-
- 帧冻结:帧冻结的绘制耗时超过 700ms,为严重卡顿问题。
- 卡顿忽略 FPS<=2 的页面:因为人的视觉暂留 100~400ms,即 FPS 在 2.5~10 之间时,所以当 FPS 低于 3 时,人眼看到的并不是连续动作,即使有丢帧现象,也不会察觉。
- FPS和卡顿无任何关系:假如1s内,前800ms刷新了50帧,但是由于卡顿最后200ms刷新了1帧。这1s的帧率为51帧,从fps上来看51帧已经非常好了,但是用户在这1s内会感觉到一次明显的卡顿。
三、Jank 计算方法:
-
-
- 当前帧耗时>两帧电影帧耗时 (1000ms/24*2=84ms,低于24帧画面,人眼就能感知到画面不连续性)。
- 严重卡顿 BigJank(同上):
- 当前帧耗时>前三帧平均耗时 2 倍。
- 当前帧耗时>三帧电影帧耗时 (1000ms/24*3=125ms)。
-
四、卡顿标准:
目前了解到某游戏大厂的卡顿率是5%以下,我们主要是app页面,所以我建议:
- 卡顿不要高于10%,对于高级别项目要求不能超过5%
- 当页面切换时,系统会产生一些超大帧,导致卡顿率上升,可以忽略
- 中端机FPS不低于56
五、实际测试中需要关注的场景:
-
- 只需关注FPS,理论PFS应该为0,否则,说明页面有冗余刷新,可能是bug,容易引起手机发热及耗电。
- 有滚动动画页面窗口
- 只需关注FPS,FPS处于合适值即可,无需高频刷新,一般fps20以上。
- 快速滑动页面窗口(同"四"中的标准)
- 需要关注FPS、卡顿率,手机交互灵敏度就是来源于此。
- 播放视频、游戏页面窗口
- 需要关注FPS、Jank及卡顿率,一般帧率20-24帧,卡顿率5%以下,目前高端机可以做到60-90帧。
六、测试方法:
- 工具类:perfdog、totorobox、Snapdragon Profiler 等
- 脚本类:adb官方命令行,通过adb命令获取并计算卡顿率、丢帧率、FPS等指标,测试前需要在手机的开发者选项中,找到“GPU呈现模式分析”,选择“在adb shell dumpsys gfxinfo中”
- 静止页面、banner滚动等通过工具做测试,不再赘述
- 常规测试中我们更关注可快滑的长列表页面,以下主要针对快滑场景的流畅度测试
1、计算每次滑动时系统记录的数据:
# 使用系统命令获取帧率数据# 以下为示例代码:def get_fps(pkg_name, devices): #fps 测试_adb = "adb -s " + devices +" shell dumpsys gfxinfo %s" % pkg_nameos.system("adb -s " + devices +" shell dumpsys SurfaceFlinger --latency-clear")# 初始化数据,如fps、卡顿时间、丢帧率、卡顿率等all_result={"jankFrames": 0, # jank次数,跳帧数"totalFrames" : 0, # 统计的总帧数...}results = os.popen(_adb)flag=Falseevery_frame_Time= [] # 每帧耗时for line in results.readlines():line=line.strip()if flag and line :times = line.split("\t")# 计算一帧所花费的时间if len(times)>3:onceTime = float(times[0])+float(times[1])+float(times[2])+float(times[3])every_frame_Time.append(onceTime)all_result['alltime']+=onceTimeall_result['totalFrames'] += 1 # 统计总帧数if onceTime > 16.67: # 以Android定义的60FPS为标准all_result['test_alltime']+=onceTimeall_result['jankFrames'] += 1# 统计跳帧jank数all_result['vsyncOverTimes'] +=int(onceTime / 16.67) # 向下取整即可else:all_result['test_alltime']+=16.67# 普通卡顿 Jank条件:if len(every_frame_Time)>=3:if onceTime>(every_frame_Time[-1]+every_frame_Time[-3]+every_frame_Time[-2])/3*2:all_result['jankTime']+=onceTimeif all_result['totalFrames'] >0:all_result['fps'] = all_result['totalFrames'] / (all_result['totalFrames'] + all_result['vsyncOverTimes']) * 60all_result['lostFrameRate'] = all_result['jankFrames'] / all_result['totalFrames']...# print("fps(1秒内平均画面刷新次数)值为:",fps)# print("总帧数:",totalFrames)else:print("【ERROR】无FPS信息,请确认手机正常连接或APP正常运行")return all_result
讯享网
2、计算滑动周期内的所有数据平均值:
讯享网# 以下为示例代码:def record_fps(sencens,t):global stopavg_all_reuslt= {"jankFrames": 0, # jank次数,跳帧数"totalFrames" : 0, # 统计的总帧数...}while True:if stop==0:all_result=get_fps(package, serialno)avg_all_reuslt['jankFrames']+=all_result['jankFrames']avg_all_reuslt['totalFrames']+=all_result['totalFrames']...else:breakif avg_all_reuslt['totalFrames'] >0:avg_all_reuslt['fps'] = round( avg_all_reuslt['totalFrames'] / (avg_all_reuslt['totalFrames'] + avg_all_reuslt['vsyncOverTimes']) * 60,4)avg_all_reuslt['lostFrameRate']=round( avg_all_reuslt['jankFrames'] / avg_all_reuslt['totalFrames'],4)avg_all_reuslt['jankRate'] =round( avg_all_reuslt['jankTime'] / avg_all_reuslt['test_alltime'],4)...记录每个场景的自动化值if t==0:allJson_result[sencens]=[avg_all_reuslt,]else:allJson_result[sencens].append(avg_all_reuslt)# 数据入库示例代码insert_mysql(devices,sencens.allJson_result)stop = 0
示例:不同维度的聚合,能否反映出不同版、不同时间段的性能的数据,可进行版本数据监控,历史版本数据对比,示例:

七、总结:
在实际测试当中,我们主要关注三个指标:FPS、卡顿率、丢帧率即可,通过这三个指标能够清晰地反映出当前app的体感现状,对于后期制定标准、促进优化效果、提高产品质量都会有一定的帮助;当然我们也可以根据可视化工具来辅助测试,来提升测试准确度,通过脚本能够弥补可视化工具的不足,脚本能够做成自动化,以节约测试时间和人力成本,提升效率。
*完整代码,关注公众号后,赞赏留言获取!
长按关注QuTest,定期分享技术干货,欢迎投稿!


版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容,请联系我们,一经查实,本站将立刻删除。
如需转载请保留出处:https://51itzy.com/kjqy/64605.html