你学会了些什么210607?--移动端性能测试方法与指标

APP移动端性能测试流程

性能需求分析

  • 参加需求评审,设计评审,跟产品、开发确定好性能测试范围和性能目标。
  • 针对不同的功能以及业务场景确定不同的性能指标(例如静态页面FPS值应该是0,页面中- 有gif图FPS又应该稳定在某个值)。
  • 根据测试设备的配置的不同确定不同的性能指标,通常高端机型的性能指标要高于中低端机型。

测试环境准备

测试设备选择

整体上从内存层面看,4G机型用户覆盖层面最广,覆盖用户数占比37.6%,6G以上用户整体占比达到50.1%。3G用户8.7%,2G以下的机型用户覆盖数只有2.6%。所以Android测试设备选用4G内存的设备比较合适。

APP移动端性能测试主要内容

  • 启动时间:主要测试app在启动过程中的耗时情况
  • 内存:主要测试app在使用过程中对内存的消耗,验证在使用过程中无内存泄漏的情况
  • CPU:主要测试app在使用过程中占用CPU的占比率
  • FPS:测试app流畅度异常的情况
  • GPU过度渲染:可以发现app流畅度异常的情况
  • 电量:主要测试app在使用过程中所消耗的电量
  • 流量:主要测试app在使用过程中所消耗的流量

APP移动端性能测试指标:

启动时间:
测试内容

  • 冷启动速度
  • 热启动速度
  • 完全启动速度
  • 有网启动速度
  • 无网启动速度
  • 主要测试冷启动和热启动

冷热启动的定义

  • 冷启动:当启动应用时,后台没有该应用的进程,这时系统会重新创建一个新的进程分配给该应用,这个启动方式就是冷启动。
  • 热启动:当启动应用时,后台已有该应用的进程(例:按back键、home键,应用虽然会退出,但是该应用的进程是依然会保留在后台,可进入任务列表查看),所以在已有进程的情况下,这种启动会从已有的进程中来启动应用,这个方式叫热启动。
    测试标准
    测试标准:冷启动时间不超过1.5s, 热启动不超过1s
    测试方法
  • 方法1:通过FFmpeg录屏拆帧
  • 官网:https://ffmpeg.org/ffmpeg.html
  • 常用命令:https://www.jianshu.com/p/91727ab25227
  • 帧率算法:
  • 方法2:使用adb
    adb shell am start -W packageName(包名)/ActivityName(活动名)(绝对路径,首个Activity)
    adb shell am start -W (包名)/(活动名)

优化方案(建议)

安卓:

1:数据处理及延迟应用启动速度放在异步线程中

在Application的构造器方法、attachBaseContext()、onCreate()方法中不要进行耗时 操作的初始化,一些数据预取放在异步线程中,可以采取Callable实现。

对于sp的初始化,因为sp的特性在初始化时候会对数据全部读出来存在内存中,所以这个初始化放在主线程中不合适,反而会延迟应用的启动速度,对于这个还是需要放在异步线程中处理。

2:GPU渲染考虑延迟加载策略及耗时操作

对于MainActivity,由于在获取到第一帧前,需要对contentView进行测量布局绘制操作,尽量减少布局的层次,考虑StubView的延迟加载策略,当然在onCreate、onStart、onResume方法中避免做耗时操作。

ios:

1:减少动态库的引用

2、合并动态库。

3、尽量不使用内嵌(embedded)的dylib,加载内嵌dylib性能开销较大。

4、清理项目中冗余的类、category。对于同一个类有多个category的,建议进行合并。

5、将不必须在+load方法中做的事情延迟到+initialize中。

6、尽量不要用C++虚函数(创建虚函数表有开销),不要在C++构造函数中做大量耗时操 作。

内存

  • 在Android系统中,每个APP进程除了同其他进程共享内存(shared dirty)外,还独用私有内存(private dirty),通常我们使用PSS(私有内存+比例分配共享内存)来衡量一个APP的内存开销

测试点

  • 空闲状态:切换至后台或者启动后不做任何操作,消耗内存最少
  • 中强度状态:时间偏长的操作应用
    (查看测试机是否卡顿严重)
  • 强度状态:高强度使用应用,可以跑monkey,或重复操作资源消耗高的场景来测试(通常用来测内存泄漏)
  • 内存泄漏:指应用里的内存一直没有释放,内存一直增加,系统内存一直减少(常出现app闪退)
    关注点
  • 退出某个页面后,内存是否有回落
  • 进行某个操作后,内存是否增长过快,一般增量建议50M
  • 旧版本和新版本比较
  • 新版本和竞品比较
    测试方法
  • 方法1:使用adb命令
    adb shell dumpsys meminfo packageName
    获取当前活动的包名和actively(adb shell dumpsys window | findstr mCurrentFocus)(mCurrentFocus---当前焦点)
    关注参数
    native heap alloc(JNI层的内存分配)
    dalvik heap alloc (java层的内存分配)
    pss:应用真正占据的内存大小
    注意:如果前两个值一直增长,应用程序可能出现了内存泄漏
  • 方法2:使用性能测试工具emmagee
    Emmagee是网易开发的一款测安卓应用性能的测试apk
    使用方法
    安装到emmagee到手机上,启动
    选择需要测试性能的应用启动
    被测应用界面会展示内存、cpu、电流、流量等数据
    stop test后,本地sd卡中会保存一份性能测试数据((保存地址:/sdcard/Emmagee/******* .csv文件))
    可以通过excel将数据转化为图表,更直观的查看各性能指标的数据
  • 方法3:使用AndroidStudio 自带 CPU 和内存检测功能 -- Android Monitor
  • 方法4:内存检测工具 DDMS -->Heap
  • 方法5:使用perfdog即可动态获取当前Memory(推荐使用)
    注意事项
    主要有几方面的原因导致内存占用高:
  • 使用了不合理的API
  • 网络下载的图片过大
  • 第三方库的缓存机制
  • Masonry布局框架
  • 没必要常驻内存的对象,实现为常驻内存
  • 数据模型中冗余的字段
  • 内存泄漏
    优化文章请参考:
    https://www.jianshu.com/p/b4b7957481b5
    https://www.jianshu.com/p/8662b2efbb23
    https://www.cnblogs.com/kekouwen/p/10403876.html

CPU

主要关注的是cpu的占用率
测试点

  • 在空闲时间(切换至后台)的消耗,基本没大应用使用cpu
  • 在运行一些应用的情况下,cpu已占50%的情况下,观察应用程序占用cpu的情况
  • 在高负荷的情况下看cpu的表现(cpu应该是在80%以上)
  • 具体场景:
    1、应用空闲状态运行监测CPU占用率
    空闲状态:应用按Home键退到后台,不再占用系统的状态(通常是灭屏半分钟后),CPU占用率=0%
    2、应用中等规格运行监测CPU占用率
    中等规格:模拟用户最常见的使用场景,CPU占用率≤30%
    3、应用满规格长时间正常运行监测CPU占用率
    Monkey测试,CPU占用率≤30%
    4、应用正常运行期间监测CPU占用率峰值
    应用正常运行:打开应用进行基本操作,CPU占用率≤50%
    关注点
  • 和自身app的上个版本对比
  • 和竞品对比
  • 自身app各个activity对比
  • 主流手机玩游戏20%-40%的CPU占用率,重点关注CPU占用率超过80%已上的情景(
    可能导致应用卡死和闪退)
    测试方法
  • 方法1:使用adb
    adb shell top -m cpu |grep packageName(查看某个软件的cpu占用率)
    adb shell top -m 10 -s cpu (查看cpu占用前10的应用)
    top cpu 参数:
    -m 显示最大数
    -s 按指定行排序
    -t 显示进程名称
    -n 在退出前刷新几次
    -d 刷新间隔
    adb shell dumpsys cpuinfo |grep 包名(一段时间的平均值)
  • 方法2:使用第三方工具Emmagee、GT、perfdog等
    (推荐使用perfdog)
    方法3:使用androidstudio自带的检测工具android monitor
    优化方案
    1:对象创建
  • 对象创建时,轻量对象代替重量对象
  • 对象不涉及UI操作,则尽量放到后台线程创建
  • 尽量推迟对象创建的时间,并把对象的创建分散到多个任务中去
  • 对象的复用代价比释放,创建新对象要小,这类对象应当尽量放到一个缓存池里复用
    2:对象调整
  • UIView的关于显示相关的属性(frame/bound/transform)等实际上都是CALayer属性映射来的,所以对UIView的这些属性进行调整时,消耗的资源要远大于一般的属性,所以,尽量减少不必要的属性修改
  • 当视图层次调整时,UIView,CALayer之间会出现很多方法调用与通知,所以,应尽量避免调整视图层次,添加和移除视图。
    3:布局计算
  • 视图布局的计算是App中最为常见的消耗CPU资源的地方,在后台线程提前计算好视图布局,并且对视图布局进行缓存
  • *用任何技术对视图进行布局,最终都会落到对UIView.frame/bounds/center等属性的调整上 对象调整:非常消耗资源,所以尽量提前计算好布局,在需要时一次性调整好对应属性,而不要多次,频繁的计算和调整这些属性
    4:控制一下线程的最大并发数量
    5:尽量把耗时的操作放到子线程
    优化文章请参考:
    https://www.cnblogs.com/HackHer/p/6351460.html
    https://www.jianshu.com/p/0ff6136d20ef
    通过实现TableView来理解ios编程: https://yishuiliunian.gitbook.io/implementate-tableview-to-understand-ios/uikit/uikit/windows-and-views/1-1-2
    FPS(应用的使用流畅度)
    fps是指画面每秒传输的帧数,每秒钟帧数越多,所显示的动作就会越流畅,一般来说安卓设备的屏幕刷新率为60帧/秒,要保持画面流畅不卡顿,要求每一帧的时间不超过1000/60=16.6ms,否则就会出现跳帧、画面卡顿
    关注点
  • FPS:帧率(1秒内平均画面刷新次数)
  • Jank:1s内卡顿次数(BigJank:1s内严重卡顿次数)
  • FrameTime:上下帧画面显示时间间隔
  • Stutter(卡顿率):测试过程中,卡顿时长的占比。即Stutter(卡顿率)=卡顿时长/总时长
    测试方法
  • 方法1:adb命令
    打开手机:开发者选项->GPU呈现模式分析->在adb shell dumpsys gfxinfo
    操作要测试的app
    在cmd窗口输入adb shell dumpsys gfxinfo 包名
    得到一个矩阵数据,计算矩阵中帧率大于16的点所占比例,即为卡顿比
    Draw: 表示在Java中创建显示列表部分中,OnDraw()方法占用的时间。
    Process:表示渲染引擎执行显示列表所花的时间,view越多,时间就越长。
    Execute:表示把一帧数据发送到屏幕上排版显示实际花费的时间。
    Draw + Process + Execute = 完整显示一帧 ,这个时间要小于16ms才能保证每秒60帧
    Janky frames:丢帧率
  • 方法2:直接使用开发者选择自带的图标
    打开手机:开发者选项->GPU呈现模式分析->在屏幕上显示为条形图
    操作要测试的app
    绿色的线是16ms的分隔线,可以直接看出来流畅度
  • 方法3:
    使用第三方工具Emmagee、GT、perfdog等
  • 方法4:
    使用androidstudio自带的检测工具android monitor
    GPU渲染
    GPU渲染是指在一个像素点上绘制多次(超过一次),过度绘制对动画性能的影响是极其严重的,如果你想要流畅的动画效果,那么一定不能忽视过度绘制。
    测试指标
  • 控制过度绘制为2x
  • 不允许存在4x过度绘制
  • 不允许存在面积超过屏幕1/4的3x过度绘制
    测试方法
  • 方法1:使用手机的开发者选项
    打开手机:开发者选项->调试GPU过度绘制->显示过度绘制区域
    打开被测的应用,进行操作
    颜色深的区域为过度绘制的地方
    原色:无过度绘制
    蓝色:绘制一次
    绿色:绘制两次
    浅红:绘制三次(可以优化了)
    深红:绘制四次(必须优化)
    优化
  • 尽量减少视图数量和层次
  • GPU能处理的最大纹理尺寸是4096x4096,一旦超过这个尺寸,就会占用CPU资源进行处理,所以纹理尽量不要超过这个尺寸
  • 尽量避免段时间内大量图片的显示,尽可能将多张图片合成一张图片显示
  • 尽量避免出现离屏渲染
    电量
    测试应用对电量的消耗前需要对手机本身的电量消耗有个大概了解,然后再启动待测试app看看消耗的电量增加了多少,取差值
    测试点
  • 测试手机安装目标apk前后待机功率有无明显差异
  • 常见使用场景中能够正常进入待机,待机电流在正常范围内
  • 长时间连续使用无异常耗电现象
    测试方法
    先关闭所有的应用,再打开被测app
  • 方法1:使用第三方测试工具:Emmagee、GT等,只需要测试的电流静置一晚,待机
    电流在正常范围内即可。一般是被测应用对比待机电流<=2mA。
  • 方法2:使用adb命令
    adb shell dumpsys batterystats |grep packageName
    改变手机电池状态
    手机连接电脑,默认为充电状态
    切换手机电池为非充电状态adb shell dumpsys battery set status 1
    获取电量消耗信息
    获取整个设备的电量消耗信息: adb shell dumpsys batterystats | more
    获取某个apk的电量消耗信息: adb shell dumpsys batterystats com.Package.name | more
    流量
    应用的耗流也是用户的一个重要关注点,一是节省用户的使用成本,二是流量优化能带来响应速度的优化,三是能清楚的知道每个场景需消耗的流量,确认是否有能优化的空间。
    测试点
    1、首次启动到全部加载完成耗流(冷启动)
    2、非首次启动到全部加载完成耗流(热启动)
    3、后台运行耗流
    4、运行某个场景消耗的总流量
    测试方法
    1、使用测试工具 Emmagee、GT或者perfdog
    安装应用待测apk,安装Emmagee
    首次启动--打开Emmagee,选择被测应用,待页面全部加载完成(Net Traffic数值趋于稳定)
    2、使用安卓系统自带的TCP流量计数进行人工计算
    查找app对应的Uid
    adb shell dumpsys package packageName |grep userId=
    adb shell ps |grep packageName --------先获取pid,第二列
    adb shell cat /proc/{pid}/status |grep Uid
    计算下行(下载)和上行(上传)流量情况
    步骤:
    1、获取当前下行(下载)流量
    adb shell cat /proc/uid_stat/{Uid}/tcp_rcv
    启动app至彻底启动,运行上面命令
    2、获取当前上行(上传)流量
    adb shell cat /proc/uid_stat/{Uid}/tcp_sd
    启动app至彻底启动,运行上面命令
    注意:
    1)、启动APP后的流量应多尝试几次,当不操作APP且流量值不变化时为准。
    3、使用抓包工具,
    上面的两种方法,都是直接对总的流量进行统计,如果发现某刻操作流量值异常增大,就需要我们定位到具体的请求来查找问题。 使用抓包工具可以看到具体接口的流量情况。
    电脑上先安装抓包工具Charles或者fiddler,然后安装证书,开启抓https的功能。
    移动设备设置连接WiFi,设置代理,安装证书。
    运行APP,查看接口流量使用情况
    APP性能测试报告
    性能测试报告模板
    ios测试报告链接:
    android测试报告链接:
相关推荐
muyouking114 小时前
9.Rust+Axum 测试驱动开发与性能优化全攻略
驱动开发·性能优化·rust
键盘敲没电5 小时前
【iOS】Blocks学习
学习·ios·性能优化·objective-c·cocoa
jaywangep10 小时前
vite插件:提取项目中第三方域进行dns-prefetch预连接
性能优化·vite
LuckyRich110 小时前
【仿Mudou库one thread per loop式并发服务器实现】HTTP协议模块实现
服务器·c++·http·性能优化
MrWho不迷糊10 小时前
秒杀怎么优化
后端·性能优化
API_technology14 小时前
高并发场景下的淘宝 API 开发实践:商品数据实时采集与性能优化
大数据·数据库·性能优化·数据挖掘
墨顿1 天前
模型推理的性能优化
人工智能·深度学习·性能优化·模型推理
涵信1 天前
第二十节:项目经验-描述一个React性能优化案例
前端·react.js·性能优化
向哆哆1 天前
Java 性能优化:JVM 调优的实战技巧与案例分析
java·jvm·性能优化