iPhone瀏覽器性能測試

【背景介紹】 javascript

雖然iPhone的性能愈來愈好,但app的功能也愈來愈複雜,性能歷來都是移動開發的核心關注點之一。咱們說一個app性能好,不是簡單指感受運行速度快,而應該是指應用啓動快速、UI反饋響應及時、列表滾動操做流暢、內存使用合理,固然更不能出現簡單的crash了。 java

那麼iOS的性能測試是什麼:資源消耗、內存泄漏、流量消耗、耗電功率、渲染效果、加載時間。。。 python

如下將結合iPhone瀏覽器從啓動時間、加載時間、內存佔用、CPU和流暢度等維度介紹如何完成一個iOS app的性能測試。其中會用到Apple的性能分析神器」Instruments」。 web


1、啓動時間 json

移動應用的啓動時間是用戶體驗的一個重要方面,蘋果一直建議儘量的縮短啓動時間,防止用戶不肯意使用它們。對於瀏覽器而言,因爲程序啓動時還會有教育頁和閃屏的下發,所以啓動時間的獲取顯得尤其重要。 瀏覽器

啓動時間分爲冷啓動時間和熱啓動時間,所謂的「冷啓動」,就是一個徹底沒有運行的應用的啓動時間,與熱啓動(應用已經在後臺運行,某個事件將其帶至前臺)相比,因爲此時系統還沒有創建緩存,所以冷啓動每每要較平時(熱啓動)耗費更長的時間。 緩存

要獲取準確的app啓動所需時間,最簡單的就是經過性能打點的方法。首先在main.c中添加以下代碼: app

CFTimeInterval startTimeLog; async

int main(int argc, char *argv[]) { ide

startTimeLog = CACurrentMediaTime();

 

而後在AppDelegate的回調方法application:didFinishLaunchingWithOptions中添加:

dispatch_async(dispatch_get_main_queue(), ^{

       CGFloat launchTime = CACurrentMediaTime() - startTimeLog;

       NSLog(@"launch: %f", launchTime);

});

 

可能你會疑問爲何這樣能夠得到系統啓動的時間,由於這個dispatch_async中提交的工做會在app主線程啓動後的下一個runloop中運行,此時app已經完成了載入而且將要顯示第一幀畫面,也就是系統會運行到-[UIApplication _reportAppLaunchFinished]以前。

 

下圖是用Instruments工具Time Profiler跑的調用棧信息。

907a3ea9f8642843ff079091dcf66878.jpg

圖1

因此使用Time Profiler一樣能夠查看app的啓動時間,具體方法以下:

  1. 1.    Instruments->Time Profiler

  2. 2.    Profiler你的app

  3. 3.    切換到CPU strategy view,找到你的app啓動的第一幀

  4. 4.    搜索-[UIApplication _reportAppLaunchFinished]的最後一幀,便可算出啓動時間(圖中爲_reportMainScreenUpdateFinished:)

 

爲了拿到真實的用戶數據,追蹤版本之間的數據變化,目前瀏覽器線上版本中啓動時間已做爲性能埋點上傳,這樣咱們就能夠計算出每日不一樣機型不一樣OS的平均啓動時間,以幫助更加實時有效的監控線上的性能質量數據。

 

2、網頁加載時間

據Google Analytics數據,目前移動網頁平均加載時間至少須要7秒,Google的目標是把這個時間降至1秒,由於參考Nielsan Norman Group 的調查研究結果:若是移動網頁加載時間超過 1 秒,用戶就不肯停留在頁面上了。

在目前的技術基礎上,在幾百毫秒內加載數個網頁幾乎是不可能實現的,但在1秒內完成移動網頁首頁內容加載是有可能的,而剩餘內容則慢慢加載。所以網頁加載首屏展示時間成爲了衡量手機瀏覽器的一個重要性能指標,計算方法爲從開始加載網頁到首屏內容所有展示所用的時間。

網頁加載時間一樣能夠基於打點的方法得到。移動網頁的加載都是從Webview的url請求開始的,webview的操做都會有UIWebviewDelegate的方法代理完成,所以經過對webview代理方法的研究(見下圖),選取正確的方法做爲開始時間和結束時間,便可獲取網頁的首屏加載展示時間和網頁加載完成時間。

530fbc977bd0e7ef121fede7677f3eb3.jpg

圖2

對於競品,咱們則能夠在越獄機型上經過動態庫hook的方法進行加載時間的計算,簡單介紹以下:

  1. 1.    class-dump-z命令得到應用程序的類信息

  2. a)      導出設備上預裝應用的類信息(/Applications)

  3. b)      導出從AppStore下載的app的類信息,須要clutch命令破解(/var/mobile/Applications)

  4. 2.    用GDB或Cycript進行運行時分析(Cycript是一個理解Objective-C語法的javascript解釋器),hook當前運行的進程,打印當前運行的viewcontroller及對應的方法名;

  5. 3.    動態庫注入,執行method swizzling,在對應的方法中打印時間日誌


關於如何使用運行時分析及動態庫注入,這裏就不詳細說明了。

固然,加載時間的查看也能夠藉助於Apple的性能分析神器Instruments。當咱們發現App有點卡的時候,就能夠經過Time Profiler來查看耗時在哪裏,如圖突出的範圍就是步驟消耗的時間。

0d12cf26a270bc9811a910adea87bb66.jpg

圖3

在這裏同時分享一個基於攝像+分析的快速進行啓動時間和加載時間計算的方法。當前手機的攝像頭基本上都支持高FPS的拍攝,拍下來的MP4文件能夠經過免費的Avidemux工具來看具體的幀信息,也能夠看到幀的時間戳,根據拍攝的格式,目前我測試的視頻能夠達到30毫秒級別,徹底知足性能測試的需求。

 

3、內存測試

iOS系統中內存限制是較爲嚴格的,所以內存優化也就成了iOS app一直以來的難題。關於內存測試的方法有不少,能夠直接用Xcode真機Debug查看,也能夠經過Instruments中內存相關的模板Activity Monitor得到。

00e012936d506a52eb679d61e66c461f.jpg

圖4 Xcode調試查看內存

 

06585f0a7d1600277102cb57481e85d3.jpg

圖5 Activity Monitor查看內存

 

在實際性能測試中,內存測試每每會分場景進行,經過腳本模擬用戶經常使用場景操做,分析該場景下的內存佔用狀況。

1.    指定run.js腳本測試

$ instruments -w ${UDID} -t ${template} ${APP} -e UIASCRIPT ${script} > .input.log


2.    解析ActivityMonitor模板的trace文件,生成對應的json格式數據

$ instruments_parser -p process_name -i result.trace

 

其中一個json塊數據格式參照以下:

{

    "Threads" : 12,

    "UnixSyscalls" : 14314,

    "Command" : "com.baidu.ime.Ba",

    "VirtualSize" : 718213120,

    "ContextSwitches" : 5774,

    "Ports" : 166,

    "PageIns" : 4881,

    "Shared" : 12976128,

    "PPID" : 1,

    "CPUUsage" : 0,

    "UID" : 501,

    "TotalMicroSeconds" : 307788,

    "Timestamp" : 1421818303.125269,

    "VPrivate" : 29028352,

    "Date" : "2015-01-21 13:31:43:125",

    "MessagesSent" : 4042,

    "PID" : 721,

    "TotalSeconds" : 1,

    "Private" : 9338880,

    "PGID" : 721,

    "MachSyscalls" : 7186,

    "ResidentSize" : 39362560,

    "Architecture" : 16777228,

    "Faults" : 19274,

    "MessagesReceived" : 1709

  }

 

3.    統計ResidentSize、VirtualSize字段,使用python的matplotlib圖形庫生成內存變化圖表。

然而對於內存測試,若是你以爲只是須要跟蹤app的內存使用狀況,那麼你就錯了。一套完整的內存管理測試方案須要關注的點其實還有不少,好比使用Leaks分析內存泄漏,使用Allocations分析內存浪費,使用Zombie分析野指針,使用VMTracker測試虛擬內存,代碼中是否仍使用ARC機制等等。

其中關於虛擬內存的測試或許是最容易被忽略的,瀏覽器就曾經發現過實際內存佔用不高,但虛擬內存上漲很快,從而致使app由於內存不足被系統kill的問題。

那麼如何分析app的虛擬內存呢?咱們能夠經過Instruments的VM Tracker進行查看。VM Tracker主要用於記錄app的虛擬內存分配,該模板會顯示app中分配了多大的虛擬內存空間,其中多少是Dirty的內存,有多少是被映射到實際物理內存中,而且能夠顯示詳細的虛擬內存分配狀況。

 

06abceca21f6d2699a1975ec4235c6e7.jpg

圖6 VM Tracker查看虛擬內存

關於上圖中的dirty size,這裏介紹一下dirty & clean的概念。

在程序使用的內存page中,iOS區分兩種內存,一種爲clean,一種爲dirty。

clean page的概念爲全部能夠被廢棄而且從新生成的page,例如二進制代碼等從磁盤讀取的文件,例如不曾讀寫過的page,或者被標識爲可擦除的內存等。

dirty page的概念爲沒法從新生成的page,即app生成的,而且已經寫入過的page,例如使用malloc分配的heap內存,全局變量,stack內存等。

當系統發現可用內存較少時,會將resident中的clean page進行清除,當有須要使用時直接從磁盤讀取就行。系統不能卸載掉dirty memory,由於iOS是沒有內存置換機制的。當dirty memory達到一個上限時,應用會被kill,由系統回收內存。

說到上限,這裏可能有人會問,在iOS設備中打開不少app後,打開被測app,該app佔用內存的上限能達到多少呢?咱們能夠經過demo app,手動malloc內存,也能夠經過instruments查看,觀察內存警告時,App被kill時的日誌輸出。

下表列出了對各類設備進行測試後獲得的數值,供你們參考。

7283204e7598e99cac2ab776114ecc50.jpg

圖7 不一樣設備內存佔用限制

4、CPU測試

CPU測試的方法和內存較爲相似,能夠經過Instruments中的Activity Monitor模板查看,也能夠經過客戶端打點的方法獲取。

在瀏覽器性能測試中,重點模塊的CPU測試還須要針對不一樣機型不一樣Architecture指令集進行兼容。例如在iPhone瀏覽器播放內核庫的測試中就須要兼容armv七、armv7s、arm6四、i38六、x86-64五種CPU上都通過測試。

wKiom1bNUa7S7Cb8AABIBV9NKVw182.png


5、流暢度

對於瀏覽器而言,會存在着較多網頁瀏覽、動畫顯示等操做,這時是否存在卡頓對於用戶體驗就顯得較爲重要。關於流暢度的測試咱們能夠經過使用instruments的core animation工具,瀏覽網頁或加載動畫,查看fps的幀數。通常而言,當用戶操做時,若是fps幀數小於40,則說明存在卡頓的情形。

21de3a0bb3658b5530e2d13643a13e0a.jpg

圖8 Core Animation查看fps幀數


    百度將於近期推出技術類圖書《如何高效地開發一款高質量的移動APP》(名稱待定),這將是百度首次技術輸出,選題聚焦在移動互聯網領域,內容覆蓋APP開發、部署、測試、分發、變現、監控和數據分析的全過程。幫助移動APP開發者,更好的瞭解百度的領先技術、項目經驗以及自主研發工具等。

    做爲業界領先的移動應用一站式測試服務平臺,百度MTC覆蓋移動應用從開發、測試到上線、運營的整個生命週期,爲廣大開發者在移動應用開發測試過程當中面臨的成本、技術和效率問題提供解決方案。本次出書稿件將陸續在MTC學院發表(http://mtc.baidu.com/academy/article),同步覆蓋其餘技術論壇,並將在今年上半年集結成冊,正式出版發行,敬請期待吧!

>>若有問題,歡迎與我溝通

相關文章
相關標籤/搜索