Categories
程式開發

開源stagesepx:全自動化的App啟動耗時測試工具


背景

對於端側應用而言,啟動耗時是個非常重要的性能指標:它的快慢很大程度上決定了用戶第一印象的好壞,與用戶的實際體驗密切相關。

而正因為它的地位舉足輕重,在敏捷開發逐漸成為主流的今天,我們不得不在每一輪迭代中都對它進行重複回歸。而隨著迭代周期逐漸縮短,發布頻次逐漸增加,重複回歸帶來的副作用也日益沉重,讓我們不得不開始思考如何進行優化。

行業現在是怎麼做的

一般來說分為兩個方向:

  • 以埋點插樁為代表的開發向;
  • 以視頻數幀為代表的質量向;

埋點

埋點方案的應用在開發領域非常廣泛,它也幾乎是進行性能優化的唯一參考。以android為例,常見做法是在各類組件生命週期相關的回調函數中,插入部分代碼(諸如日誌、網絡請求等)對調用行為進行標註。如此做之後,當應用進行常規的生命週期切換時,我們就能夠通過這些帶有時間戳的標註得到每個階段的具體耗時。

開源stagesepx:全自動化的App啟動耗時測試工具 1

這種做法非常細緻,我們幾乎能夠得到任意函數級別的耗時情況,這也讓我們能夠在此基礎上建立 benchmark 以控制後續的行為。目前大多數的全鏈路監控都是基於類似的方法實現的。

但,它得到的代碼層面的數據,與實際用戶感受到的情況是有差距的,這也是質量人員對此並不感冒的原因。

視頻

原理非常直接:

  • 利用諸如攝像機之類的設備將整個應用的啟動過程錄製成視頻
  • 對視頻進行拆幀
  • 由於每一幀都有對應的時間戳,我們可以通過計算得到任意兩幀之間的差值
  • 同理我們能夠得到任意場景的耗時情況

開源stagesepx:全自動化的App啟動耗時測試工具 2

這種方法與用戶的實際感受基本一致,能夠較好地反映真實情況,也是一般質量側用得最多的方法。但這種方法帶來的問題是,我們只能計算能夠被觀測到的數據,而對於不可見的(例如具體函數耗時)部分我們無從得知。

異同與優劣

目前來說,這兩種方法都有相當數量的用戶,在行業內並存。追根溯源,是關注點的差異導致了這兩股人群的分化:

  • 開發人員更關注的是“優化”。埋點得到的信息能夠幫助開發人員更好地知悉並評估代碼執行過程的變化,找到優化點;
  • 質量人員更關注的是“體驗”。視頻得到的信息反饋了用戶的真實感受,也是最終應用呈現的狀態,而這正是質量人員需要牢牢把控的;

綜上而言,這兩者通常會結合使用,以配合得到更好的結果。

難點

埋點方案已經廣泛地應用到全鏈路監控中,各類成熟的解決方案層出不窮,並不是一個很難解決的問題。

視頻方案上,目前我們很大程度上依舊只能依賴 外置攝像機+人工數幀 的方式,這種不可編程的方式優化空間非常有限。而這種方式被大量應用到各類准入准出標準中,是一個難以避開的問題。

本篇文章將聚焦於視頻方案的優化與解決。

優化點與方案

最終目的

我們希望將視頻方案上消耗的人力最大限度地降低。這其中主要有兩個問題:

  • 攝像機(硬件依賴)能否替換?
  • 幀計算如何自動化?

問題分析

攝像機

之所以質量側一直不夠信任軟件錄製,主要有兩個原因:

  • 被測主體與測試工具在同一台設備上,有互相影響的可能;

開源stagesepx:全自動化的App啟動耗時測試工具 3

  • 部分軟件錄製得到的視頻fps可能是不穩定的,而這會影響opencv的分析結論;

開源stagesepx:全自動化的App啟動耗時測試工具 4

對於問題1,在過去硬件條件不夠發達的情況下確實是個客觀存在的問題。但近年來移動設備的硬件水平已經得到了非常大的提升,對於常規應用與機型而言,這部分的影響已經非常小。

對於問題2,以adb為例,這種方式帶來的誤差可能是非常巨大的。因為opencv會默認以穩定fps的情況來處理你的視頻:

開源stagesepx:全自動化的App啟動耗時測試工具 5

而 adb 的錄製原理是,當畫面發生變化時才會將幀寫入視頻,這會導致整個視頻的fps存在較大的波動。

自動化的幀計算

因為作為前提的攝像機錄製目前沒有很好的解決方案,所以自動計算受到了很大的限製而難以開展。目前比較常見的方式是利用目標檢測來自動界定階段:

開源stagesepx:全自動化的App啟動耗時測試工具 6

通過判斷界面上是否存在特定標誌物,我們可以知悉目前流程進行到哪個階段,並在此基礎上進行擴展計算。但這種做法伴隨的問題同樣很多:

  • 需要額外的成本去管理標誌物圖片,而這種做法在UI頻繁變換的業務中反而引入了更大的工作量;
  • 逐幀、多目標的檢測帶來算力的浪費,隨著標誌物的增加效率會繼續下降;
  • 對於動態的標誌物(諸如每次刷新都會改變的icon)無從下手;

如何解決

對於fps不穩定的問題,有個前提是,雖然fps不穩定,但每一幀的時間戳是準確的。那麼,我們可以利用 ffmpeg 對這些視頻進行補幀,使整個視頻的fps維持在一個固定值。經過這種方法處理之後,opencv就能夠正確地處理視頻的時間。

開源stagesepx:全自動化的App啟動耗時測試工具 7

在前提得到滿足之後,我們使用 stagesepx 進行幀時間的自動計算。

stagesepx

這是什麼

輕量化的、基於圖像處理與機器學習的、全自動的視頻分析工具。它提供了豐富的可定制性,能夠根據你的實際需求分析視頻並將其拆分為一系列階段。在此之後,你可以清晰地得知視頻包含了幾個階段、以及每個階段發生了什麼。而這一切都是自動完成的。

例如,這段視頻展示了一個應用的完整啟動過程:

開源stagesepx:全自動化的App啟動耗時測試工具 8

將視頻傳遞給 stagesepx,它將自動分析拆解,得到視頻中所有的階段。包括變化的過程及其耗時,以及在穩定的階段停留的時長:

開源stagesepx:全自動化的App啟動耗時測試工具 9

你可以據此得到每個階段對應的精確耗時。而你幾乎可以將它應用到任何端,甚至:

開源stagesepx:全自動化的App啟動耗時測試工具 10

開源stagesepx:全自動化的App啟動耗時測試工具 11

而它自帶的python接口可以讓開發者很輕鬆地二次開發,以落地到實際環境。例如,將結果轉換為字典:

{
"data": [{
"data": null,
"frame_id": 1,
"stage": "0",
"timestamp": 0.0,
"video_path": "../demo.mp4"
}, {
"data": null,
"frame_id": 2,
"stage": "0",
"timestamp": 0.04,
"video_path": "../demo.mp4"
}, {
"data": null,
"frame_id": 3,
"stage": "0",
"timestamp": 0.08,
"video_path": "../demo.mp4"
}, {
    
    ...

從這個字典中我們可以知道,每一幀分別對應的:

  • 被分類到哪一個類別
  • 時間戳
  • 幀編號

用戶可以隨意處理這些數據,無論是保存或是交給下一段代碼。

全自動化

上面提到的處理過程只能滿足一些常規場景的需求,要想達到更好的泛用,它面對的一個最大問題是如何使自動化分析得到的結果與我們的預期匹配起來。例如:

  • 當偶現彈窗時會導致階段數量發生改變或後移,如果直接以階段編號進行計算的話必然是錯誤的;
  • 目前許多超級app都會具備UI動態化的設計,以達到更高的靈活度。這些都會影響階段的分類:
    • 內容型APP每次打開首頁內容都不一致
    • 插屏廣告播放的內容是隨機的
    • 遊戲某個階段場景是動態的(有循環播放的動畫等,很多遊戲的初始界面都會有)

在 0.10.0 之後,stagesepx 借助了 keras 來處理該類型問題。

開源stagesepx:全自動化的App啟動耗時測試工具 12

基於 stagesepx 的雙層結構,開發者能夠使用自己提供的訓練集干預分類過程,讓計算機能夠按照定制好的規則進行分類,以支撐後續耗時計算的準確性。

開源stagesepx:全自動化的App啟動耗時測試工具 13

具體使用可參考 全自動化的抖音啟動速度測試

性能

這套方案在沒有GPU的情況下依舊保持了較為理想的工作效率。默認配置下,在普通的windows辦公PC上,對於一個15s的視頻而言,一次分析耗時1分鐘左右。

stagesepx 提供了大量的可配置項(諸如分辨率壓縮係數),使得用戶能夠自由地在顆粒度與效率之間找到最合適的平衡。比起傳統方式,這種方法有能力大幅提高回歸次數,從而得到一個更為客觀的評估數據。

如何使用

如果你希望優化你的現有流程:

你可以直接基於上面的落地方式,以自動或人工的方式優化評估流程。

如果你在尋找最佳實踐:

一般來說,這套流程會搭配鏈路監控同步使用。如果你的業務已經具備了鏈路監控能力,你可以將該套方案添加到已有流程中,將開發側與質量側數據匯總起來達到更為全面客觀的評測效果。

相關鏈接

更多使用方式與具體原理請參考官方文檔: