当前位置:   article > 正文

移动端测试 APP启动性能分析 WebView性能分析 H5性能分析 卡顿分析 帧分析 CPU统计 网络流量分析 耗电量指标 弱网测试 健壮性测试 兼容性测试 Amdahl_webview 帧率统计

webview 帧率统计

Android官网使用指南性能:https://developer.android.com/topic/performance

一、APP启动性能分析

APP的启动过程
调用起APP、创建一个空白窗口、启动一个进程 ——> Application OnCreate 开始调用起App ——> Activity OnCreate 创建主线程MainThread(页面的渲染,数据的初始化)
在这里插入图片描述

启动性能指标
冷启动:第一次启动,无任何进程和数据
暖启动:之前启动过,存在缓存的数据
热启动:进程都还存在
首屏启动:页面完全加载完全的时间
对于以上的建议时间
Cold startup takes 5 seconds or longer 冷启动不超过5s
Warm startup takes 2 seconds or longer 暖启动不超过2s
Hot startup takes 1.5 seconds or longer 热启动不超过1.5s

主要流程

1、adb logcat 查看日志
2、录屏+视频拆祯
3、uiautomator等自动化工具200ms巡检界面变化
4、traceview
5、硬埋点 页面加载加了获取时间性能的埋点

logcat使用
package=com.xueqiu.android
清理缓存数据:adb shell pm clear $package
停止进程:adb shell am force-stop $package
执行上面的两个行为后,让启动的app变得冷启动
启动app:adb shell am start -S -W $package/.view.WelcomeActivityAlias
获取数据:adb logcat | grep -i displayed

查看结果
1、startTime: 记录刚准备调用startActivityAndWait()的时间
2、endTime: 记录startActivityAndWait()函数调用返回的时间点
3、WaitTime:startActivityAndWait()调用耗时 WaitTime = endTime - startTime
在这里插入图片描述
ffmpeg拆祯方法
作用:计算每个阶段时间
原理:先把APP停止 - 使用录屏录制启动的过程 - 获取到录制视频后(这时在模拟器),把获取到的视频拉取到本地电脑 - 然后拆祯为gif图 - 再拆成jpg图,通过1s的图拆成多少份后,计算多少张图片完成了这个加载的动作。然后用图的数量*1s拆成的分数,得出这个动作所消耗的时间。
使用说明:

package=com.xueqiu.android   测试的包名
adb shell am force-stop $package     停止测试软件
adb shell screenrecord --bugreport --time-limit 30 /data/local/tmp/Test.mp4 &   录屏30s
adb shell am start -S -W $package/.view.WelcomeActivityAlias wait
adb pull /data/local/tmp/Test.mp4   拉取录制的视频到本地
ffmpeg -i Test.mp4 Test.gif		视频拆成gif图片
ffmpeg -i Test.mp4 -r 10 frames_%03d.jpg  把gif图1s的图片拆成10份(也就是一张图片用例0.1s)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
二、WebView性能分析

开发者工具
蓝色线:DOM出现
红色线:资源加载完成
Disable cache:加载缓存
在这里插入图片描述
fiter过滤表达式
domain.展示domain中的资源,*.com
has-response-header.包含指定HTTP响应header
is. 表达式
larger-than.展示大于某个尺寸的资源,1000等于1k
method.指定http请求方法,比如get或者post
mime-type.资源mime类型,比如application/json
scheme.HTTP(scheme.http)或者HTTPS(scheme:https).
status-code.状态码
在这里插入图片描述
performance使用
在这里插入图片描述
加载详情
在这里插入图片描述
对应字段说明:https://developers.google.com/web/tools/chrome-devtools/network/reference?utm_source=devtools#timing-explanation

手机浏览器性能分析
原理:通过inspect把手机中的webview页面加载到PC端的浏览器中,然后通过浏览器的开发者工具查看
inspect使用注意点
1、模拟器使用6.0默认支持
2、物理机需要打开app内开关
在这里插入图片描述
3、PC端使用的chrome浏览器版本62.XXX (防止控制台样式异常)

三、H5性能分析

W3C性能说明:https://www.w3.org/TR/navigation-timing/
在这里插入图片描述
资源加载指标说明
prompt for unload:访问一个新页面时,旧页面卸载完成的时间
redirect:重定向,用户注销登陆时返回主页面和跳转到其他的网站等
app cache:检查缓存,是否打开
DNS(域名系统):DNS查询时间,如果时长连接或者请求文件来自缓存等本地存储则返回fetchStart时间点
TCP:与服务器建立链接的时间
request:浏览器发起请求的时间
response:拿到第一个响应字节到最后一个响应字节的时间
processing:各种状态的时间点
load:触发load事件执行的时间
获取单个页面资源的性能

window.performance.timing
  • 1

在这里插入图片描述
获取对应的操作码

window.performance.navigation.type
  • 1

跳转 0
刷新 1
后退 2
JS模拟的基本操作

window.history.back()  //  返回
window.history.forward()   //  前进
window.location.reload()   //  刷新
window.location.href="https://www.baidu.com/"   //跳转到某个页面
window.location.href   // 查看本地的url
  • 1
  • 2
  • 3
  • 4
  • 5
from appium import webdriver
from selenium.webdriver.common.by import By

def test_APP():
    desire_cap = {
        "platformName": "android",
        "deviceName": "emulator-5554",
        "appPackage": "com.xueqiu.android",
        "appActivity": ".view.WelcomeActivityAlias",
        "noReset": True,  # 保存缓存,  热启动
    }
    driver = webdriver.Remote('http://127.0.0.1:4723/wd/hub',desire_cap)
    driver.implicitly_wait(16)
    driver.find_element(By.XPATH,"//*[@text='交易']").click()
    webview = driver.contexts[-1]
    driver.switch_to.context(webview)

    print(driver.execute_script("return window.performance.navigation.type"))
    driver.execute_script("window.location.href='https://www.baidu.com/'")
    driver.execute_script("window.location.reload()")
    print(driver.execute_script("return window.performance.navigation.type"))
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
四、卡顿分析

方式一、systrace SDK 自带分析工具
1、位置:sdk/platform-tools/systrace
2、需要使用python2.7
3、启动过程遇到少的文件,按需install
使用

1、启动设备:python systrace.py -e 192.168.181.102:5555 -l
不加参数启动开始录制:python2 systrace.py
2----运行模拟器上的对应要测的Activity----
3、停止录制手机报告:按下enter
4、在sdk/platform-tools/systrace获取报告trace.html
  • 1
  • 2
  • 3
  • 4
  • 5

在这里插入图片描述
结果查看
在这里插入图片描述
详细信息
1、帧点
绿色:16.6ms内,黄色,红色超过16.6ms
2、任务状态
灰色:休眠 蓝色:可运行 橙色:不响应
3、函数调用

方式二、dumpsys gfxinfo

 adb shell dumpsys gfxinfo com.xueqiu.android
  • 1

在这里插入图片描述
查看具体信息

 adb shell dumpsys gfxinfo com.xueqiu.android
  • 1

在这里插入图片描述

在这里插入图片描述
使用matplotlib图形绘制

from matplotlib import pyplot

def test_draw():
    import subprocess
    cmd = "adb shell dumpsys gfxinfo com.xueqiu.android"
    res = subprocess.Popen(cmd,shell=True,stdout=subprocess.PIPE,stderr=subprocess.PIPE)
    # print(str(res.stdout.read(),encoding='utf-8'))
    lines = res.stdout.readlines()  # readlines()获取的是list
    # print(lines)
    i = 1
    # 判断下是否是对应的包
    for line in lines:
        i += 1
        if "com.xueqiu.android.common.MainActivity" in line.decode("utf-8"):
            break
    # 使用列表生成式,对获取的数据处理,并获取新的lines列表
    lines = [data.decode("utf-8").replace("\r\n","").replace("\t"," ").strip() for data in lines]
    lines = lines[i:i + 120]  # 获取i行到i+120行的数据
    print(lines)
    datas = [[] for row in range(4)]  # 生成一个空的二维数组 [[],[],[],[]]
    # lines = [14.84 0.2 6.17 11.58,14.00 0.4 6.66 11.11,.....]
    for x in lines:
        datas[0].append(float(x.split()[0]))  # 获取lines中每组数据的第1个值  14.8,并且添加到datas[[14.8,],[],[],[]]
        datas[1].append(float(x.split()[0]))  # 获取lines中每组数据的第1个值  14.8,并且添加到datas[[14.8,],[0.2],[],[]]
        datas[2].append(float(x.split()[0]))  # 获取lines中每组数据的第1个值  14.8,并且添加到datas[[14.8,],[0.2],[6.17],[]]
        datas[3].append(float(x.split()[0]))  # 获取lines中每组数据的第1个值  14.8,并且添加到datas[[14.8,],[0.2,],[6.17,],[11.58,]]
    # print(datas)

    # 绘制成图
    fig = pyplot.figure() # 生成一个画板
    # num = 1
    # for n in datas:
    #     ax = fig.add_subplot(2,2,num)  # 生成一个2*2图形
    #     ax.plot(n)  # 绘制第一个数组的图  plot折线
    #     num += 1
    # pyplot.show()

    # 分组绘制4个图  如果绘制到一个图中,fig.add_subplot(X,X,1),最后一个数字都改为1
    ax1 = fig.add_subplot(2,2,1)
    ax1.plot(datas[0])  # 折线图
    ax1.set_title("Draw")  # 标题
    ax1 = fig.add_subplot(2,2,2)
    ax1.scatter(range(120),datas[1])  # 散点图
    ax1.set_title("Prepare")
    ax1 = fig.add_subplot(2,2,3)
    ax1.hist(datas[2],range(5)) # 柱状图
    ax1.set_title("Process")
    ax1 = fig.add_subplot(2,2,4)
    ax1.plot(range(120),datas[3],'--k')  # 虚线图
    ax1.set_title("Execute")

    pyplot.show()
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52

在这里插入图片描述
datas处理后数据形式
在这里插入图片描述
注意 ⚠️ : gfxinfo信息会有实效性,时间长了就获取不到了,注意刷新和模拟器中开发者选项中“GPU呈现模式分析”

卡顿影响因素

内存问题 (内存抖动、full gc)
cpu (计算耗时)
render(布局复杂、overdraw)

五、帧分析

冰冻帧:一个帧超过0.7s (橙色、红色)
帧分析:adb -s devicesname shell dumpsys gfxinfo | less

六、CPU统计

CPU与GPU关系
1、图形API不允许CPU直接与GPU通信,会通过Graphics Driver中间件进行连接
在这里插入图片描述
2、过程:CPU进行数据的处理 —> 处理后到Graphics Driver,Graphics Driver会维护一个队列,CPU把display list放入队列。—> GPU从队列去数据进行绘制
在这里插入图片描述
GPU渲染工具
Android开发者工具提供性能调优工具
GPU渲染分析:GPU-RENDERING-PROFILE
在这里插入图片描述

在这里插入图片描述
GPR显示内容
1、绘制每一帧所消耗的时间
2、不同的颜色代表UI绘制的不同阶段
3、并且子啊柱状图的中间还有一根绿色的横线代表16ms的绘制时间基准
4、GPR会统计并显示app最近运行的128帧
在这里插入图片描述
在这里插入图片描述
蓝色
View需要先转换为GPU能识别的格式(中间件处理的过程)
蓝色较高

  • view突然无效(invalidate) ->队列中的数据失效,view:绘制布局、样式、事件等的一个容器
  • onDraw函数中做了复杂的绘制逻辑 (onDraw函数:绘制图形的函数)
    在这里插入图片描述
    红线
    OpenGL处理DISPLAYIST,将处理结果传递给GPU (即中间件处理过程,红色代表中间件负载过高)
    红色较高:
    view过于复杂
    view重复提交

橙色
CPU在等待GPU完成工作 (GPU绘制的过程)
橙色较高
GPU任务负载过高,view绘制太复杂

不同颜色的意义(Android官网https://developer.android.com/topic/performance/rendering/inspect-gpu-rendering
在这里插入图片描述
在这里插入图片描述

mem统计(手机内存统计)对于app的内存的优化,我们通常只是对不同版本对比,不看实际的占用多少

内存耗用名词
在这里插入图片描述
指标解析
VSS:衡量虚拟内存大小五太大用处。无法知道分配的物理内存大小
RSS:个进程的RSS相加,会超过系统内存使用量(不是按比例分配)
PSS:个进程的PSS之和,就是系统的内存使用量 (按比例分配的)
USS:是PSS中自己的部分,不包含任何共享的部分 (app之间交换使用共同的数据会产生共享的内存)

内存占用大小规律:
VSS>=RSS=>PSS>=USS

查看内存第一种方式:procstats
adb shell dumpsys procstats --hours 3 (查看3小时内的内存使用情况)
输出信息
在这里插入图片描述
输出格式
进程详情
进程名称/USER/VersionCode
状态:minPSS-avgPSS-maxPSS/minUSS-avgUSS-maxUSS

输入字段解释
百分比:表示在总的时间内,进程在各种状态下的消耗
例如:100%,就指在这段时间内,这个进程是一直处于运行当中的
TOTAL:表示进程的总和占用情况
Img Fg:加载到前台
Service:标示了是否是服务
Persistent:标识了是否一直驻留子在内存当中,与Service一样,标示内存进驻的级别
Top:标识了是否是顶层进程
Receiver:标识了是否是广播进程

查看内存第二种方式:meminfo
查看指定的进程mem:

adb shell dumpsys meminfo com.xueqiu.android(包名)
  • 1

在这里插入图片描述
meminfo内容
在这里插入图片描述

网络流量分析

网络分析

adb shell dumpsys netstats
  • 1

分块展示
Activity interfaces:活动接口
Activity UID interfaces:活动UID接口
Dev statistics:开发统计信息
Xt statistics:Xt统计信息
UID statistics:UID统计信息
UID tag statistics:UID代码统计信息
活动接口和活动UID接口
在这里插入图片描述
开发统计信息/Xt统计信息
在这里插入图片描述
UID统计信息
在这里插入图片描述
获取对应应用UID

adb shell dumpsys package com.xueqiu.android | grep userId
输出:userId=10000 gids=[2002,1023,3134]
  • 1
  • 2

查看相关应用的流量情况
set=DEFAULT 表示前台网络使用情况
set=BACKGROUND表示后台使用情况
set=ALL表示上述两类使用情况
tag=0x0表示与流量关联的套接字代码
rxBytes 和 rxPackets 表示在相应时间间隔内接收的字节数(rb)和数据包数(rp)
txBytes 和 txPackets 在相应时间间隔内发送的字节数(tb)和数据包数(tp)

查看对应网络的情况
如果使用模拟器会出现报错,可以换成真机
在这里插入图片描述
使用过程

adb shell dumpsys package com.xueqiu.android | grep userId  获取userId
adb shell dumpsys package netstats | grep 12321(UID信息)		获取网络信息,并且使用userId过滤
  • 1
  • 2

结果:
在这里插入图片描述

耗电量指标(在真机上测)

目的:通过不同的测试场景,找出APP高耗电的场景解决
常见电量问题
唤醒锁(acquire)
关闭屏幕显示,让CPU后台运行
app长期获取唤醒锁,不释放
阻止设备进入低电量模式
耗电标准
电池会话:再次充满电之间
消耗整个电池会话的0.70%
在后台运行时,消耗整个电池会话的0.10%

调用唤醒锁存在的问题

void doSomethingAndRelease() throwsMyException{
	wakeLock.acquire();
	doSomethingThatThrows();  //当这里出现报错的时候,下面锁的释放将无法关闭。导致其他应用无法使用
	wakeLock.release();
	}
  • 1
  • 2
  • 3
  • 4
  • 5

改进

void doSomethingAndRelease() throwsMyException{
	
	try{
		wakeLock.acquire();
		doSomethingThatThrows();  
	}finally{
		wakeLock.release();
		}
	}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
测试方式

方式一、测试性能使用Google Playhttps://play.google.com/store/apps

方式二、Battery Historian工具
GitHub地址:https://github.com/google/battery-historian
安装
注意:要在python2.7环境下执行,安装好go语言

git clone https://github.com/google/battery-historian.git
cd battery-historian
go get -d -u github.com/google/battery-historian/...
go run setup.go
# cd $GOPATH/src/github.com/google/battery-historian
go run cmd/battery-historian/battery-historian.go [--port <default:9999>]
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

具体步骤:
1、git clone https://github.com/google/battery-historian.git 或者直接下载后解压
2、进入battery-historian文件,打开终端
3、执行go get -d -u github.com/google/battery-historian/...
4、进入setup.go,更改版本为20190513,最稳定版本
在这里插入图片描述
5、开始编译,执行go run setup.go
6、启动:go run cmd/battery-historian/battery-historian.go [--port <default:9999>]

测试步骤
使用batterystats生成数据
使用Battery historian分析数据
batterystats收集数据
1、清理耗电量数据
adb shell dumpsys batterystats --reset
adb shell dumpsys batterystats --enable full-wake-history
2、运行测试用例/手工操作
3、收集数据
Android 7.0:adb bugreport bugreport.zip
Android 6.0: adb bugreport>bugreport.txt
上传数据
打开localhost:9999,把zip或者txt数据上传
在这里插入图片描述
报告生成
在这里插入图片描述
Historian
x轴代表时间周期,默认以60s为一个周期
在这里插入图片描述
指标含义:
battery_level:电量
plugged:充电状态及充电时长
screen:屏幕是否点亮
top:显示当前手机运行的app
status:电池状态信息,有充电、放电、未充电、已充满,未知等不同状态

方式三、dumpsys
在这里插入图片描述
建议:https://developer.android.com/guide/background

弱网测试

弱网问题
封闭环境,网速降低

  • 丢包
  • 数据无法加载
  • 消息更新不及时等
    模拟弱网
    使用charles模拟弱网
    官网下载:https://www.charlesproxy.com/download/
    使用charles
    1、代理设置,设置端口
    Proxy -> Proxy Setting
    在这里插入图片描述
    2、设置本地代理 (如果代理模拟器,在手机网络中的代理设置本地的IP和端口)
    本地电脑网络设置 - > 代理 - 地址 (一般就是默认值)
    在这里插入图片描述
    在这里插入图片描述
    3、开启节流
    Proxy -> Throttle Settings -> Enable Throttling
    在这里插入图片描述
    名词解释
    Bandwidth (带宽) 理论网速上限 100MB大概下载速度是12Mb
    Utilisation (利用) 总带宽的百分比
    Round-trip Latency (请求往还延迟) 客户端和服务器第一次往返通信的延迟,单位毫秒
    MTU (最大传输单元) 传输的TCP数据包的最大尺寸
    Reliability (可靠性) 衡量连接完全失败的可靠性
健壮性测试

用于测试系统在出现故障时,是否能够自动恢复或者忽略故障继续运行。
操作过程
在正常情况和异常情况下(弱网,数据不同等)进行长时间操作 (通常使用monkey长时间操作)

兼容性测试

建议使用第三方网站测试,比如阿里云移动端测试:https://www.aliyun.com/product/mqc?spm=5176.19720258.J_8058803260.444.1c852c4aIfPwku
不同硬件、软件或者硬件之间的配合度(手机设备,系统版本,浏览器版本,分辨率等)
APP兼容性测试
移动设备型号多样
测试APP在主流设备上能否正常运行
测试APP在主流设备奔溃卡顿现象

APP性能

移动端APP运行在shell和Linux是相同的,所以我们查看APP性能,可以使用所有Linux查看性能的方法。
在这里插入图片描述
字段解释:r:排队数量b:阻塞数量swpd:虚拟内存free空闲内存buff缓冲cache缓存si虚拟内存换入so虚拟内存换出bi磁盘换入 bo磁盘换出 in中断次数 cs切换次数 us使用CPU时间 sy系统CPU时间 id空闲CPU时间 wa 等待IO CPU时间

打印对应应用实时信息
在这里插入图片描述
使用bash提取对应的指标
获取vmstat最后一行的第4个数

adb shell vmstat | tail -1 | awk '{print $4}'
  • 1

在这里插入图片描述
循环提取

while true;do adb shell vmstat | tail -1 | awk '{print $4}'; done 
  • 1

使用Python代码获取

def test_vmstat():
    cmd = 'adb shell vmstat'
    res = subprocess.Popen(cmd,shell=True,stdout=subprocess.PIPE,stderr=subprocess.PIPE)
    # print(res.stdout.readline())
    # 获取vmstat信息,获取的是b字节,使用str转码,转码后以"\r\n"切割,然后获取第3个数
    print(str(res.stdout.read(),encoding="utf-8").split("\r\n")[2].split()[3])
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
Amdahl定律

作用:1、改善任何过程的一般原则 2、加速计算机系统估值
参数:
S:加速比
a: 系统某部分所需时间与总时间的比例
k:性能提升比例
在这里插入图片描述

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/从前慢现在也慢/article/detail/300926
推荐阅读
相关标签
  

闽ICP备14008679号