01 | App啟動性能分析
基本的測試checklist和手段
專項測試(用戶維度)
- 崩潰(Crash趣兄,弱網(wǎng))
- 卡頓(掉幀,gc翻具,cpu)
- 響應(yīng)慢(啟動時間履怯,交互響應(yīng),H5加載)
- 發(fā)熱(cpu裆泳,mem诈铛,io寻行,network妖枚,gps等硬件使用)
- 掉電快(硬件占用)
- 兼容性問題(機型覆蓋鳍寂,回歸)
專項測試(技術(shù)維度)
- 崩潰(自動遍歷,monkey測試闻葵,橫豎屏切換民泵,快速進退)
- 卡頓(卡頓測試,內(nèi)存泄漏測試槽畔,method profile)
- 響應(yīng)慢(冷仍啟動栈妆,界面切換,h5性能測試)
- 發(fā)熱(method profile厢钧,gc統(tǒng)計鳞尔,io統(tǒng)計,流量統(tǒng)計早直,硬件使用統(tǒng)計寥假,耗電量分析)
- 兼容性問題(兼容性測試,自動化測試霞扬,自動遍歷糕韧,monkey測試)
app性能
- android應(yīng)有由很多的activity組成拾给,這些activity的耦合度比較低
-
activity的啟動流程
- 主要流程
1.Application OnCreate(加載第三方的sdk等)
2.Activity OnCreate(加載自身邏輯,發(fā)送遠程數(shù)據(jù)請求兔沃,渲染界面List)
app啟動性能指標(biāo)
- 冷啟動(進程已被kill,或新安裝的應(yīng)用)建議小于5s
- 暖啟動(app在后臺久了级及,會被內(nèi)存管理kill乒疏,此時用戶重啟應(yīng)用),建議小于2s
- 熱啟動(app在后臺運行)饮焦,建議小于1.5s
- 首屏啟動(加上了stuff時間)
測試工具和方法
- adb logcat
- 錄屏+視頻拆幀:把1s拆成10幀怕吴,人工數(shù)幀,可以計算首屏啟動時間
- uiautomator等自動化工具县踢,每隔200ms打印page_source的變化
- traceview:android的分析工具
- 硬埋點:最準(zhǔn)確转绷,app啟動前后植入埋點,再把數(shù)據(jù)回傳到服務(wù)器硼啤,需開發(fā)配合议经,不常用
adb logcat 使用
package=com.xueqiu.android
-
adb shell pm clear $package
清除緩存 -
adb shell am force-stop $package
停止進程 -
adb shell am start -S -W $package/.view.WelcomeActivityAlias
啟動app -
adb logcat | grep -i displayed
獲取數(shù)據(jù)
adb logcat結(jié)果
- startTime:記錄剛準(zhǔn)備調(diào)用startActivityAndWait()的時間點
- endTime:記錄startActivityAndWait()函數(shù)調(diào)用返回的時間點
- WaitTime:startActivityAndWait()調(diào)用耗時(endTime - startTime)
- TotalTime:創(chuàng)建進程+創(chuàng)建object+創(chuàng)建activity的時間
使用ffmpeg拆幀
adb shell am force-stop $package
adb shell screenrecord --bugreport --time-limit 30 /data/local/tmp/xueqiu.mp4 &
adb shell am start -S -W $package/.view.WelcomeActivityAlias # 或手動點擊
adb pull /data/local/tmp/xueqiu.mp4 .
ffmpeg -i xueqiu.mp4 xueqiu.gif
ffmpeg -i xueqiu.mp4 -r 10 frames_%03d.jpg
02 | 接口性能
工具
- 代理工具:charles,burpsuite
1.電腦的流量都會經(jīng)過charles谴返,再到服務(wù)器
2.抓到請回和返回數(shù)據(jù)的內(nèi)容 - 抓包工具:tcpdump煞肾,wireshark
1.主動請求服務(wù)器,抓取服務(wù)器返回的數(shù)據(jù)包
2.監(jiān)聽端口嗓袱,抓取發(fā)送和返回的數(shù)據(jù)包
03 | webview性能分析
簡介
- WebView是android中一個非常重要的控件籍救,它的作用是用來展示一個web頁面。它使用的內(nèi)核是webkit引擎渠抹,4.4版本之后蝙昙,直接使用Chrome作為內(nèi)置網(wǎng)頁瀏覽器。
chrome檢查中的關(guān)鍵選項
- Disable cache:不加載緩存梧却,從零載入
- 藍色線:dom出現(xiàn)
-
紅色線:圖片等資源已加載完
- timing各字段:
1.waiting:服務(wù)器響應(yīng)時間
https://cloud.tencent.com/developer/article/1083690
手機瀏覽器性能分析
04 | H5性能分析
參考資料
資源加載指標(biāo)
- prompt for unload:訪問新頁面時奇颠,舊頁面卸載完成時間
- redirect:重定向,用戶注銷登錄返回主頁面或跳轉(zhuǎn)到其他網(wǎng)站
- app cache:檢查緩存是否打開
- DNS:DNS查詢時間篮幢,若是長連接或請求文件來自緩存等本地存儲則返回fetchStart時間點
- TCP:與服務(wù)器建立連接的時間
- request:瀏覽器發(fā)起請求的時間
- response:拿到第一個響應(yīng)字節(jié)到最后一個響應(yīng)字節(jié)的時間
- processing:各種狀態(tài)的時間點
- load:觸發(fā)load事件執(zhí)行時間
獲取單個資源的性能
瀏覽器 -> console -> PerformanceTiming
自動化獲取性能指標(biāo)
- chrome -> console :
1.window.performance.timing
2.window.performance.timing.responseEnd - window.performance.timing.responseStart
- python代碼
from selenium import webdriver
class TestPerformance():
def test_performance(self):
driver = webdriver.Chrome()
driver.get("http://www.baidu.com")
print(driver.execute_script("return JSON.stringify(window.performance.timing)"))
05 | CPU統(tǒng)計
CPU與GPU的關(guān)系
- 圖形api不允許CPU直接與GPU通信
- 通過中間層鏈接CPU和GPU
- 中間層維護一個隊列
- CPU把display list放入隊列
-
GPU從隊列取數(shù)據(jù)進行繪制
GPU渲染工具
- android開發(fā)者模式提供性能調(diào)優(yōu)工具:開發(fā)者選項 - GPU呈現(xiàn)模式分析 - 在屏幕上顯示為條形圖
GPR顯示內(nèi)容
- 繪制每一幀所消耗的時間
- 不同顏色代表UI繪制的不同階段
1.官方資料:https://developer.android.com/topic/performance/rendering/inspect-gpu-rendering - 柱狀圖的中間有一根綠色的橫線大刊,代表16ms繪制時間基準(zhǔn)
- GRP會統(tǒng)計并顯示app最近運行的128幀
06 | mem統(tǒng)計
名詞解釋
名詞術(shù)語 | 全拼 | 解釋 |
---|---|---|
VSS | virtual set size | 虛擬內(nèi)存(包含共享庫占用的內(nèi)存) |
RSS | resident set size | 實際使用的物理內(nèi)存(包含共享庫占用的內(nèi)存) |
PSS | proportional set size | 實際使用的物理內(nèi)存(比例分配共享占用內(nèi)存) |
USS | unique set size | 進程獨自占用的物理內(nèi)存(不包含共享庫占用的內(nèi)存) |
各指標(biāo)解析
VSS:衡量虛擬內(nèi)存大小無太大用處,無法知道分配物理內(nèi)存大小
RSS:各進程的RSS相加三椿,會超過系統(tǒng)內(nèi)存使用量
PSS:各進程的RSS相加缺菌,就是系統(tǒng)內(nèi)存使用量
USS:是PSS中自己的部分,不包含任何共享部分
procstats
adb shell dumpsys procstats --hours 3
adb shell dumpsys meminfo com.xueqiu.android
輸出詳解
- 進程詳情
1.進程名稱/user/versionCode
2.狀態(tài):minPSS-avgPSS-maxPSS/minUSS-avgUSS-maxUSS - 100%:表示在總的時間內(nèi)搜锰,進程在各種狀態(tài)下的消耗(100%即在這段時間伴郁,進程一直處于運行當(dāng)中)
- total:表示進程的綜合占用情況
- Imp Fg:加載到前臺
- Service:標(biāo)識是否是服務(wù)
- Persisitent:標(biāo)識是否一直駐留在內(nèi)存,與service一樣表示內(nèi)存進駐的級別
- Top:標(biāo)識是否是頂層進程
- Receiver:標(biāo)識是否是廣播進程
補充
同一時間有多個應(yīng)用占用內(nèi)存蛋叼,測內(nèi)存要對比不同版本的內(nèi)存大小
07 | 網(wǎng)絡(luò)流量分析
顯示網(wǎng)路流量
adb shell dumpsys netstats
找到應(yīng)用UID
adb shell dumpsys package com.xueqiu.android | grep userId
-
adb shell dumpsys netstats | grep 10051
1.rb:receive byte
2.rp:receiver package
3.tb:transport byte
4.tp:transport package
08 | 卡頓分析
cpu焊傅、網(wǎng)絡(luò)剂陡、內(nèi)存都有可能引起卡頓
systrace
- sdk/platform-tools/systrace
- 須python2.7
運行中遇到的問題
- 提示"No module win32com"
解決:pip2 install pypiwin32
- 提示"No module six"
解決:pip2 install six
使用
cd D:\Programs\android-sdk-windows\platform-tools\systrace
-
python systrace.py -e 設(shè)備 -l
進入錄制模式,在設(shè)備上操作狐胎,命令行按下enter結(jié)束錄制鸭栖,并在systrace目錄下生成result
查看報告
- 藍點:警告
- cpu
- 指定app
- 綠色圓點:代表每一幀,點擊綠色圓點握巢,按M鍵顯示加載時間
- 函數(shù)調(diào)用
- 任務(wù)狀態(tài):灰-休眠晕鹊,藍-可運行,綠-運行暴浦,橙-不響應(yīng)
- 常用命令:w-放大溅话,s-縮小,m-找到下一幀歌焦,顯示時間
卡頓影響因素
- 內(nèi)存問題(內(nèi)存抖動飞几,垃圾回收)
- cpu(計算耗時)
- render(布局復(fù)雜,overdraw)
幀分析
- 冰凍幀:一個幀超過0.7s
09 | 耗電量測試
應(yīng)用耗電過大独撇,導(dǎo)致手機過熱屑墨,cpu降頻。耗電量測試就是通過不同的測試場景纷铣,找出app高耗電的場景并解決
安裝
- golang
- python 2.7
git clone https://github.com/google/battery-historian.git
go get -d -u github.com/google/battery-historian/...
- 修改setup.go中的closureCompilerVersion="20190513"
go run setup.go
go run cmd/battery-historian/battery-historian.go
batterystats收集數(shù)據(jù)
- 清理耗電量數(shù)據(jù)
adb shell dumpsys batterystats --reset
adb shell dumpsys batterystats --enable full-wake-history
- 運行測試用例或手動操作
- 收集數(shù)據(jù)
1.android 7.0及以上:adb bugreport bugreport.zip
2.android 6.0:adb bugreport > bugreport.txt - 上傳數(shù)據(jù)
1.打開localhost:9999
2.把zip或txt上傳
查看報告
- 指標(biāo)含義
1.battery_level:電量
2.plugged:充電狀態(tài)及充電時長
3.screen:屏幕是否點亮
4.top:顯示當(dāng)前手機運行的app
5.status:電池狀態(tài)信息绪钥,充電、放點关炼、未充電程腹、已充滿、未知等
10 | 健壯性測試
測試系統(tǒng)在出現(xiàn)故障時儒拂,能否自動恢復(fù)或忽略故障繼續(xù)運行
操作過程
- 對應(yīng)用進行盲點
- 網(wǎng)絡(luò)不佳
- 數(shù)據(jù)不通
使用工具
- Monkey寸潦,Maxim,Charles社痛,Appcrawler
11 | 弱網(wǎng)測試
弱網(wǎng)問題
- 封閉環(huán)境见转,網(wǎng)速降低
1.掉包
2.數(shù)據(jù)無法加載
3.消息更新不及時
弱網(wǎng)速度
- 低于2G速率
- 3G
模擬弱網(wǎng)
-
charles代理設(shè)置
-
設(shè)置本地代理
- 開啟節(jié)流(Proxy-Throttle Setting -Enable Throttling)
名詞解釋
- Bandwidth(帶寬:理論網(wǎng)速上限)
1.上行:數(shù)據(jù)流出,如上傳
2.下行:數(shù)據(jù)流入蒜哀,如下載
3.帶寬的單位是Mbps斩箫,真實的網(wǎng)速要除以8,如帶寬是10M撵儿,真實網(wǎng)速最高可達到1.25M - Round-trip Latency(請求往返延遲)
1.客戶端與服務(wù)器第一次往返通信的延遲乘客,單位毫秒 - MTU(最大傳輸單元)
1.傳輸?shù)腡CP數(shù)據(jù)包的最大尺寸 - Reliability(可靠性)
1.衡量連接完全失敗的可能性,如為50%淀歇,則只有50%的成功率
12 | 實戰(zhàn)1
非功能測試(針對專項質(zhì)量問題的測試)
- 移動端性能問題(硬件相關(guān)易核,如cpu、mem浪默、disk牡直、network缀匕、gpu)
- 移動端場景問題(場景相關(guān),如弱網(wǎng)測試碰逸、兼容性測試乡小、國際化)
常用的測試方案
- android
1.ddms
2.android studio最新版本的集成工具
3.hook
4.代碼插樁 - IOS
1.instruments
2.hook
3.代碼插樁
app啟動性能指標(biāo)
- 首次安裝啟動:會耗費較多時間初始化,如下載補丁饵史、緩存數(shù)據(jù)
- 冷啟動:進程不存在(主要關(guān)注劲件,不超過5秒)
- 暖啟動:進程存在,界面不存在
- 熱啟動:界面對象依然存在约急,只是從后臺切到前臺
- 首屏啟動:第一屏加載完成
測試啟app動性能的方法
- logcat觀察啟動時間
- 錄屏拆幀
- 注:通常殺掉進程,不清理數(shù)據(jù)
web性能
https://developers.google.com/web/tools/chrome-devtools/network/reference#timing-explanation
13 | 實戰(zhàn)2
chrome中network的使用
- 藍線:dom 加載完成
- 紅線:所有資源加載完成
- 捕獲:查看加載圖片
- 根據(jù) waterfall 排序 苗分,進行資源篩選
- shift 查看資源依賴關(guān)系
chrome模擬手機
- setting-devices厌蔽,勾選手機
chromer中performance的使用
- record button
- screenshorts
- Diable JavaScript samples 禁用js樣例,禁用后調(diào)用關(guān)系簡單很多
-
Enable advanced paint instrumentation
appium性能獲取
from appium import webdriver
from selenium.webdriver.common.by import By
class TestWebview:
_package = "com.xueqiu.android"
_activity = ".view.WelcomeActivityAlias"
def test_webview(self):
caps = dict()
caps["platformName"] = "android"
caps["deviceName"] = "hogwarts"
caps["appPackage"] = self._package
caps["appActivity"] = self._activity
caps["noReset"] = True
# 需要對應(yīng)版本的 chromedirver 摔癣,才能在 webview 中執(zhí)行 js 代碼
caps["chromedriverExecutable"] = "C:/develop/chromedriver/chromedriver2.20.exe"
# 初始化driver
self._driver = webdriver.Remote(
"http://localhost:4723/wd/hub",
caps)
self._driver.implicitly_wait(15)
# 進入到 webview
self._driver.find_element(By.XPATH, "http://*[@text='交易']").click()
# 切換上下文到 webview
webview = self._driver.contexts[-1]
self._driver.switch_to.context(webview)
# 執(zhí)行 js 代碼奴饮,獲取性能數(shù)據(jù)
all_time = self._driver.execute_script("return window.performance.timing")
# 對數(shù)據(jù)進行二次操作
response_time = all_time['responseEnd'] - all_time['responseStart']
print(response_time)
使用adb shell 獲取cpu的使用率
while true;do adb shell top -n 1 | grep xueqiu | awk '{print $3}';done
14 | 實戰(zhàn)3
https://www.w3.org/TR/navigation-timing/#performancenavigation
navigation
TYPE_NAVIGATE = 0
TYPE_RELOAD = 1
TYPE_BACK_FORWARD = 2
-
window.performance.navigation.type
新打開頁面,type的初始值是0择浊,隨著頁面操作戴卜,type的值隨之變化;如刷新頁面琢岩,type的值變?yōu)?
使用js模擬瀏覽器動作
window.history.back()
window.history.forward()
window.location.reload()
window.location.href=“https://www.baidu.com/"
window.location.href # 獲取當(dāng)前網(wǎng)址
將手機內(nèi)容下載到本地
adb pull ///data/user/0/com.xueqiu.android/files/h5/modules_new/xueqiu.com ~/Desktop/xueqiu.com
查看webview網(wǎng)址
adb logcat | grep http
adb logcat -c
清除logcat
喚醒鎖
https://developer.android.google.cn/topic/performance/vitals?hl=en
- 喚醒鎖阻止設(shè)備進入睡眠模式投剥,若喚醒鎖不釋放,耗電量會很高
-
adb shell dumpsys power
查看喚醒鎖
- 避免使用喚醒鎖
https://developer.android.google.cn/guide/background - 喚醒鎖改進:使用前臺服務(wù)
https://developer.android.google.cn/guide/components/services#Foreground
Amdahl定律
- S:加速比
- a:系統(tǒng)某部分所需時間與總時間的比例
-
k:性能提升比例
Amdahl特殊情況
-
考慮k->無窮