1 整体思路
闲鱼在业务的快速迭代过程中,app 的长列表滑动流畅度逐步恶化,对用户浏览内容体验产生伤害。闲鱼作为国内 flutter 应用的先驱,APP 以 flutter 和原生 Native 的混合工程存在。这里分别就 Android 原生、flutter 页面和大家分享我们的优化思路。
本文分为三个部分:
流畅度指标和检测工具构建
原生 Android 长列表优化
flutter 长列表优化
流畅度优化整体思路图如下:
2 流畅度指标和检测工具构建
2.1 现状和难点
检测工具现状:以 Android 为例,现有流畅度工具可分为:
侵入式
-
集成 sdk,通过注册帧回调计算流畅度。Android 见 Choreographer 类
profile 模式
无侵入式
-
执行系统命令,如
adb shell dumpsys gfxinfo ${packageName}
腾讯 GT APP,底层执行
service callSurfaceFlinger1013
,高版本 Android 已不支持
流畅度指标现状有:
FPS (Frames Per Second)
SF(SkippedFrame,跳帧) app 在单位时间 1 秒内,跳过执行 Choreographer 中 doFrame() 的次数
SM(Smooth,流畅度) app 在单位时间 1 秒内,实际执行 Choreographer 中 doFrame() 的次数。其中 SM=60-SF。
帧耗时数据 使用 adb 命令得到几个关键分位的帧平均耗时:
然而以上工具和指标定义在 app 的复杂场景下,尚存在问题
多平台问题
现 APP 技术有原生、h5、小程序、RN、weex、flutter 等。暂无一款无侵入的流畅度检测工具能同时支持多个平台、多种机型和多个指标数据,而侵入式的检测工具无法检测竞品 APP。
指标选择和用户体验一致性
我们期望能有少量的几个指标数据,准确的表达用户流畅度体感。平均 FPS(SM 和 SF 类似),不足以反映用户体验。如相同 30 FPS,可以是 1s 内 30 个 33.3 ms的画面,也可以是 29 个 16.6ms 的画面再加 1 个 516.9 ms 的画面,但用户体验并不相同。
流畅度数据影响因素多
滑动速度和滑动状态:idle(停止)、drag(手指拖拽)、fling(自由滑动)都是影响流畅度数据的重要因素。
2.2 流畅度指标制定
维基百科中动画定义:一种通过定时拍摄一系列多个静止的固态图像(帧)以一定频率连续变化、运动(播放)的速度(如每秒16张)而导致肉眼的视觉残象产生的错觉——而误以为图画或物体(画面)活动的作品及其影片技术。
列表滑动同理,是 APP 以一定频率(60hz下16.6ms)和不同 offset 计算出一系列静止画面,让肉眼看到滑动动画。
当我们说列表滑动不流畅,是因为频率过低无法让肉眼产生视觉残留,或在时间(画面停留时长)和空间(画面内容)产生跳变,让用户感知到变化的不自然。以此我们可以定义指标如下:
时间角度
-
定义平均 FPS:定义一次检测的平均帧率。反应画面平均停留时长。
定义 1s 大卡顿次数:平均 1s 内出现占用 3 帧及以上的画面次数。反应画面停留时长跳变
空间角度
-
offset 跳变值:在画面不掉帧的情况,若其中一个画面出现跳变,甚至花屏或者绿屏会让用户体验到不流畅。在 APP 滑动过程中,画面内容由 offset 决定,而 offset 跳变,和卡顿时长、差值器实现均有关联,现有差值器实现基本基于 D/T 曲线(距离/时间),为此平均 FPS 和 1s 大卡顿次数很大程度上体现了画面跳变,同时考虑到无侵入式检测 offset 的难度问题,暂不考虑 offset 跳变值。
综上,我们定义流畅度指标为平均 FPS 值和 1s 大卡顿次数。
2.3 流畅度检测工具实现
我们从 APP 录屏画面入手,计算流畅度指标值。当我们得到 APP 滑动过程中的录屏数据,可通过每 16.6ms 检测录屏画面是否发生变化,当连续画面未发生变化,则表示发生了卡顿。无变化的连续画面数则表示了卡顿的时长。
为得到目标 APP 录屏数据,检测工具 APP 向系统注册录屏服务,然后在检测工具 APP 的帧回调中不停读取录屏画面,并和上次检测画面 hash 值进行比对。
检测工具 APP 和目标 APP 进程隔离,为此目标 APP 发生卡顿并不影响检测工具 APP 的帧回调
为保证每次录屏画面读取和 hash 值计算在 16.6ms 内完成,需根据高低端机型调整画面宽高压缩比。
为排除滑动操作对流畅度数值的干扰,我们使用脚本操作检测工具 APP 和目标 APP 的滑动。自动化脚本原理为使用 adb 命令操作手机
2.4 检测工具演示
流畅度检测工具 APP 以悬浮框的方式显示,下面为目标检测 APP:
流畅度检测工具界面
2.5 小结和展望
在流畅度指标方面,我们定义了平均 FPS 和 1s 大卡顿次数作为指标,更好的反应了用户体验。在流畅度检测工具方面,我们实现了无侵入检测工具,支持以下特性:
无侵入
支持检测第三方 app
支持多平台:native,flutter,h5,小程序
多维度数据:平均 FPS,平均 1s 大卡帧次数,