您好,登錄后才能下訂單哦!
【背景介紹】
雖然iPhone的性能越來越好,但app的功能也越來越復雜,性能從來都是移動開發的核心關注點之一。我們說一個app性能好,不是簡單指感覺運行速度快,而應該是指應用啟動快速、UI反饋響應及時、列表滾動操作流暢、內存使用合理,當然更不能出現簡單的crash了。
那么iOS的性能測試是什么:資源消耗、內存泄漏、流量消耗、耗電功率、渲染效果、加載時間。。。
以下將結合iPhone瀏覽器從啟動時間、加載時間、內存占用、CPU和流暢度等維度介紹如何完成一個iOS app的性能測試。其中會用到Apple的性能分析神器”Instruments”。
一、啟動時間
移動應用的啟動時間是用戶體驗的一個重要方面,蘋果一直建議盡可能的縮短啟動時間,防止用戶不愿意使用它們。對于瀏覽器而言,由于程序啟動時還會有教育頁和閃屏的下發,因此啟動時間的獲取顯得尤為重要。
啟動時間分為冷啟動時間和熱啟動時間,所謂的“冷啟動”,就是一個完全沒有運行的應用的啟動時間,與熱啟動(應用已經在后臺運行,某個事件將其帶至前臺)相比,由于此時系統尚未建立緩存,因此冷啟動往往要較平時(熱啟動)耗費更長的時間。
要獲取準確的app啟動所需時間,最簡單的就是通過性能打點的方法。首先在main.c中添加如下代碼:
CFTimeInterval startTimeLog;
int main(int argc, char *argv[]) {
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跑的調用棧信息。
圖1
所以使用Time Profiler同樣可以查看app的啟動時間,具體方法如下:
1. Instruments->Time Profiler
2. Profiler你的app
3. 切換到CPU strategy view,找到你的app啟動的第一幀
4. 搜索-[UIApplication _reportAppLaunchFinished]的最后一幀,即可算出啟動時間(圖中為_reportMainScreenUpdateFinished:)
為了拿到真實的用戶數據,追蹤版本之間的數據變化,目前瀏覽器線上版本中啟動時間已作為性能埋點上傳,這樣我們就可以計算出每日不同機型不同OS的平均啟動時間,以幫助更加實時有效的監控線上的性能質量數據。
二、網頁加載時間
據Google Analytics數據,目前移動網頁平均加載時間至少需要7秒,Google的目標是把這個時間降至1秒,因為參考Nielsan Norman Group 的調查研究結果:如果移動網頁加載時間超過 1 秒,用戶就不愿停留在頁面上了。
在目前的技術基礎上,在幾百毫秒內加載數個網頁幾乎是不可能實現的,但在1秒內完成移動網頁首頁內容加載是有可能的,而剩余內容則慢慢加載。因此網頁加載首屏展現時間成為了衡量手機瀏覽器的一個重要性能指標,計算方法為從開始加載網頁到首屏內容全部展現所用的時間。
網頁加載時間同樣可以基于打點的方法獲得。移動網頁的加載都是從Webview的url請求開始的,webview的操作都會有UIWebviewDelegate的方法代理完成,因此通過對webview代理方法的研究(見下圖),選取正確的方法作為開始時間和結束時間,即可獲取網頁的首屏加載展現時間和網頁加載完成時間。
圖2
對于競品,我們則可以在越獄機型上通過動態庫hook的方法進行加載時間的計算,簡單介紹如下:
1. class-dump-z命令獲得應用程序的類信息
a) 導出設備上預裝應用的類信息(/Applications)
b) 導出從AppStore下載的app的類信息,需要clutch命令破解(/var/mobile/Applications)
2. 用GDB或Cycript進行運行時分析(Cycript是一個理解Objective-C語法的javascript解釋器),hook當前運行的進程,打印當前運行的viewcontroller及對應的方法名;
3. 動態庫注入,執行method swizzling,在對應的方法中打印時間日志
關于如何使用運行時分析及動態庫注入,這里就不詳細說明了。
當然,加載時間的查看也可以借助于Apple的性能分析神器Instruments。當我們發現App有點卡的時候,就可以通過Time Profiler來查看耗時在哪里,如圖突出的范圍就是步驟消耗的時間。
圖3
在這里同時分享一個基于攝像+分析的快速進行啟動時間和加載時間計算的方法。當前手機的攝像頭基本上都支持高FPS的拍攝,拍下來的MP4文件可以通過免費的Avidemux工具來看具體的幀信息,也可以看到幀的時間戳,根據拍攝的格式,目前我測試的視頻可以達到30毫秒級別,完全滿足性能測試的需求。
三、內存測試
iOS系統中內存限制是較為嚴格的,因此內存優化也就成了iOS app一直以來的難題。關于內存測試的方法有很多,可以直接用Xcode真機Debug查看,也可以通過Instruments中內存相關的模板Activity Monitor獲得。
圖4 Xcode調試查看內存
圖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的內存,有多少是被映射到實際物理內存中,并且可以顯示詳細的虛擬內存分配情況。
圖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時的日志輸出。
下表列出了對各種設備進行測試后得到的數值,供大家參考。
圖7 不同設備內存占用限制
四、CPU測試
CPU測試的方法和內存較為類似,可以通過Instruments中的Activity Monitor模板查看,也可以通過客戶端打點的方法獲取。
在瀏覽器性能測試中,重點模塊的CPU測試還需要針對不同機型不同Architecture指令集進行兼容。例如在iPhone瀏覽器播放內核庫的測試中就需要兼容armv7、armv7s、arm64、i386、x86-64五種CPU上都經過測試。
五、流暢度
對于瀏覽器而言,會存在著較多網頁瀏覽、動畫顯示等操作,這時是否存在卡頓對于用戶體驗就顯得較為重要。關于流暢度的測試我們可以通過使用instruments的core animation工具,瀏覽網頁或加載動畫,查看fps的幀數。一般而言,當用戶操作時,如果fps幀數小于40,則說明存在卡頓的情形。
圖8 Core Animation查看fps幀數
百度將于近期推出技術類圖書《如何高效地開發一款高質量的移動APP》(名稱待定),這將是百度首次技術輸出,選題聚焦在移動互聯網領域,內容覆蓋APP開發、部署、測試、分發、變現、監控和數據分析的全過程。幫助移動APP開發者,更好的了解百度的領先技術、項目經驗以及自主研發工具等。
作為業界領先的移動應用一站式測試服務平臺,百度MTC覆蓋移動應用從開發、測試到上線、運營的整個生命周期,為廣大開發者在移動應用開發測試過程中面臨的成本、技術和效率問題提供解決方案。本次出書稿件將陸續在MTC學院發表(http://mtc.baidu.com/academy/article),同步覆蓋其他技術論壇,并將在今年上半年集結成冊,正式出版發行,敬請期待吧!
>>如有問題,歡迎與我溝通
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。