阿里技术团队整理:闲鱼APP长列表流畅度翻了倍(良心教程)

简介: 从“麻绳版顺滑”到“丝般顺滑”

作者:闲鱼技术-云从

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 call SurfaceFlinger 1013,高版本 Android 已不支持

流畅度指标现状有:

  • FPS (Frames Per Second)
  • SF(SkippedFrame,跳帧)
  1. 在单位时间 1 秒内,跳过执行 Choreographer 中 doFrame() 的次数 (见 《移动App性能评测与优化》
  • SM(Smooth,流畅度)
  1. 在单位时间 1 秒内,实际执行 Choreographer 中 doFrame() 的次数。其中 SM=60-SF。(见 《移动App性能评测与优化》
  • 帧耗时数据
    使用 adb 命令得到几个关键分位的帧平均耗时:
Total frames rendered: 2245
Janky frames: 31 (1.38%)
50th percentile: 5ms
90th percentile: 10ms
95th percentile: 14ms
99th percentile: 18ms

然而以上工具和指标定义在 app 的复杂场景下,尚存在问题

  1. 多平台问题
    现 APP 技术有原生、h5、小程序、RN、weex、flutter 等。暂无一款无侵入的流畅度检测工具能同时支持多个平台、多种机型和多个指标数据,而侵入式的检测工具无法检测竞品 APP。
  2. 指标选择和用户体验一致性
    我们期望能有少量的几个指标数据,准确的表达用户流畅度体感。

平均 FPS(SM 和 SF 类似),不足以反映用户体验。如相同 30 FPS,可以是 1s 内 30 个 33.3 ms的画面,也可以是 29 个 16.6ms 的画面再加 1 个 516.9 ms 的画面,但用户体验并不相同。

  1. 流畅度数据影响因素多
    滑动速度和滑动状态: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 命令操作手机

点击:adb shell input tap $x $y
滑动:adb shell input swipe $x1 $y1 $x2 $y2 $duration

2.4 检测工具演示

流畅度检测工具 APP 以悬浮框的方式显示,下面为目标检测 APP:

流畅度检测工具界面

2.5 小结和展望

在流畅度指标方面,我们定义了平均 FPS 和 1s 大卡顿次数作为指标,更好的反应了用户体验。
在流畅度检测工具方面,我们实现了无侵入检测工具,支持以下特性:

  • 无侵入
  • 支持检测第三方 app
  • 支持多平台:native,flutter,h5,小程序
  • 多维度数据:平均 FPS&
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值