Android App性能評(píng)測(cè)分析-啟動(dòng)時(shí)間篇

1、前言

隨著項(xiàng)目版本的迭代,App的性能問題會(huì)逐漸暴露出來,而好的用戶體驗(yàn)與性能表現(xiàn)緊密相關(guān),性能問題從應(yīng)用的啟動(dòng)優(yōu)化開始,下面會(huì)根據(jù)實(shí)際app性能測(cè)試案例,進(jìn)行app性能評(píng)測(cè)之啟動(dòng)時(shí)間的分析和總結(jié)。

2、App啟動(dòng)方式了解

通常來說, 一個(gè)App啟動(dòng)也會(huì)分如下三中不同的狀態(tài):

  • 冷啟動(dòng)
    當(dāng)啟動(dòng)應(yīng)用時(shí),后臺(tái)沒有該應(yīng)用的進(jìn)程,這時(shí)系統(tǒng)會(huì)重新創(chuàng)建一個(gè)新的進(jìn)程分配給該應(yīng)用,這個(gè)啟動(dòng)方式就是冷啟動(dòng),也就是先實(shí)例化Application

    冷啟動(dòng)的流程即為App啟動(dòng)流程的全過程, 需要?jiǎng)?chuàng)建App進(jìn)程, 加載相關(guān)資源, 啟動(dòng)Main Thread, 初始化首屏Activity等.

    在這個(gè)過程中, 屏幕會(huì)顯示一個(gè)空白的窗口(顏色基于主題), 直至首屏Activity完全啟動(dòng).

    下圖展示了冷啟動(dòng)的時(shí)間線:


    冷啟動(dòng)流程.png
  • 熱啟動(dòng)
    當(dāng)啟動(dòng)應(yīng)用時(shí),后臺(tái)已有該應(yīng)用的進(jìn)程,這時(shí)會(huì)從已有的進(jìn)程來啟動(dòng)Activity(不需要重新創(chuàng)建Application)

    類同與冷啟動(dòng), 在這個(gè)過程中, 屏幕會(huì)顯示一個(gè)空白的窗口(顏色基于主題), 直至activity渲染完畢.

  • 溫啟動(dòng)
    介于冷啟動(dòng)和熱啟動(dòng)之間, 一般來說在以下兩種情況下發(fā)生:

    • 用戶back退出了App, 然后又啟動(dòng). App進(jìn)程可能還在運(yùn)行, 但是activity需要重建.

    • 用戶退出App后, 系統(tǒng)可能由于內(nèi)存原因?qū)pp殺死, 進(jìn)程和activity都需要重啟, 但是可以在onCreate中將被動(dòng)殺死鎖保存的狀態(tài)(saved instance state)恢復(fù).

通過三種啟動(dòng)狀態(tài)的相關(guān)描述, 可以看出我們要做的啟動(dòng)優(yōu)化其實(shí)就是針對(duì)冷啟動(dòng). 熱啟動(dòng)和溫啟動(dòng)都相對(duì)較快.

3、性能評(píng)測(cè)結(jié)果案例分析

3.1 XX銀行 APP啟動(dòng)時(shí)間評(píng)測(cè)結(jié)果分析

3.1.1 啟動(dòng)時(shí)間測(cè)試結(jié)果

統(tǒng)計(jì)的時(shí)間為APP的冷啟動(dòng)時(shí)間,4G網(wǎng)絡(luò)情況下,平均冷啟動(dòng)時(shí)間為14.1S,平均熱啟動(dòng)時(shí)間為6.7S,無(wú)網(wǎng)絡(luò)時(shí)平均啟動(dòng)時(shí)間為5.2S。由于APP的啟動(dòng)時(shí)間耗時(shí)遠(yuǎn)遠(yuǎn)超過行業(yè)標(biāo)準(zhǔn)水平3S,當(dāng)app啟動(dòng)時(shí),任何一個(gè)地方有耗時(shí)操作都會(huì)拖慢我們應(yīng)用的啟動(dòng)速度,所以針對(duì)APP啟動(dòng)時(shí)間做了具體分析

3.1.2評(píng)測(cè)結(jié)果分析

首先來看App從點(diǎn)擊桌面圖標(biāo)到我們看到App的主界面整個(gè)過程中經(jīng)過了哪些步驟:
啟動(dòng)虛擬機(jī)—>啟動(dòng)AMS —>通過Zygote創(chuàng)建ApplicationProcess進(jìn)程–>Application的構(gòu)造器方法——>attachBaseContext()——>onCreate()——>Activity的構(gòu)造方法——>onCreate()——>配置主題中背景等屬性——>onStart()——>onResume()——>測(cè)量布局繪制顯示在界面上。

1)初始化Application
  • 【初始化Application】應(yīng)用程序初始化總共耗費(fèi)了3.26S,耗時(shí)已超過行業(yè)APP啟動(dòng)標(biāo)準(zhǔn)基線時(shí)間3S。具體看下耗時(shí)詳情分析:
    (1)應(yīng)用Application.attach的時(shí)間較長(zhǎng)。應(yīng)用存在多個(gè)dex文件,請(qǐng)控制應(yīng)用方法數(shù)量。
    (2)onCreate方法耗時(shí)長(zhǎng),主要體現(xiàn)BaseApplication創(chuàng)建上。

長(zhǎng)耗時(shí)方法排名如下:
1.com.pingan.fstandard.framework.base.BaseApplication.onCreate(BaseApplication.java)

  1. com.pingan.fstandard.common.c.a(InitManager.java)
  2. com.pafinancialtech.pafs.kitchendaddy.f.b(PAFFToast.java:83
    4.com.pingan.fstandard.HomeApplication.d(HomeApplication.java:51

綜上分析,BaseApplication創(chuàng)建上耗費(fèi)較長(zhǎng)時(shí)間,需要開發(fā)進(jìn)行更詳細(xì)的分析優(yōu)化。另外,初始化Application時(shí),也包含了任意門相關(guān)等非核心功能的程序,建議啟動(dòng)時(shí)不創(chuàng)建該類程序。

2)初始化Activity
  • 【初始化Activity】耗時(shí)也過長(zhǎng),耗時(shí)約1s左右
    主要耗時(shí)的地方是在閃屏界面創(chuàng)建oncreate時(shí)com.pingan.fstandard.activity.SplashActivity.onCreate,建議開發(fā)優(yōu)化
3)加載請(qǐng)求及響應(yīng)

首先來一張流程圖了解一下我們APP首頁(yè)加載的一個(gè)流程

頁(yè)面加載流程.png
冷啟動(dòng)資源加載.png
  • 【網(wǎng)絡(luò)請(qǐng)求及響應(yīng)】總體來看,首頁(yè)加載耗時(shí)占比最多,需要6s左右,對(duì)應(yīng)的網(wǎng)絡(luò)消耗時(shí)間占比45%左右。

根據(jù)抓包及代碼段分析顯示APP啟動(dòng)到首頁(yè)加載完成是一個(gè)預(yù)加載和異步加載的過程。
(1) 項(xiàng)目中大部分第三方組件都搶占先機(jī),在Application主線程初始化。這樣的初始化方式肯定是過重的,建議考慮異步初始化三方組件,不阻塞主線程;延遲部分三方組件(比如埋點(diǎn)統(tǒng)計(jì)、任意門、ImageLoader的初始化)。
(2) 啟動(dòng)到首頁(yè)加載完成網(wǎng)絡(luò)請(qǐng)求密集,請(qǐng)求內(nèi)容豐富,部分資源重復(fù)請(qǐng)求
請(qǐng)求了相關(guān)配置信息、啟動(dòng)頁(yè)廣告、個(gè)推、磁貼配置信息、商城理財(cái)產(chǎn)品列表,運(yùn)營(yíng)廣告Banner、F后端接口,廣告BANNER位、插件信息、任意門、百度地圖SDK(talkingdata、灰度升級(jí))等林林總總加起來就有40+個(gè)網(wǎng)絡(luò)請(qǐng)求,加載的數(shù)據(jù)+廣告頁(yè)一共有1.7M左右,這說明了我們的APP首頁(yè)設(shè)計(jì)的內(nèi)容比較豐富,部分資源重復(fù)請(qǐng)求,部分內(nèi)容需要調(diào)外部接口,所以耗時(shí)比較長(zhǎng),這是產(chǎn)品設(shè)計(jì)問題、信息未做緩存處理和部分外部關(guān)聯(lián)方接口響應(yīng)慢的原因?qū)е拢ㄗh優(yōu)化。
(3)非核心功能資源過早請(qǐng)求加載
另外其中類似百度地圖SDK、任意門、微信sdk相關(guān)插件只有在生活頁(yè)\分享時(shí)使用到的非主要業(yè)務(wù)功能啟動(dòng)時(shí)也加載出來了,建議開發(fā)同學(xué)和產(chǎn)品同學(xué)調(diào)整APP啟動(dòng)時(shí)網(wǎng)絡(luò)請(qǐng)求的加載策略,非核心/主要/高PV的功能相關(guān)的API,SDK、插件等沒有必要在啟動(dòng)時(shí)做加載緩存,這是非常耗時(shí)且得不償失的。

3.1.3啟動(dòng)時(shí)間優(yōu)化建議

(1)應(yīng)用Application.attach的時(shí)間較長(zhǎng)。應(yīng)用存在多個(gè)dex文件,請(qǐng)控制應(yīng)用方法數(shù)量。
(2)onCreate方法耗時(shí)長(zhǎng),主要體現(xiàn)BaseApplication創(chuàng)建上,需要開發(fā)進(jìn)行更詳細(xì)的分析優(yōu)化,建議考慮異步初始化三方組件,不阻塞主線程;延遲或者和產(chǎn)品一起梳理需要的去除的部分三方組件(比如統(tǒng)計(jì)、任意門、ImageLoader的初始化)。
(3)com.pingan.fstandard.activity.MainActivity存在過度繪制導(dǎo)致卡頓,首頁(yè)UI布局層次過多,建議開發(fā)進(jìn)一步分析優(yōu)化
(4)建議產(chǎn)品調(diào)整優(yōu)化app啟動(dòng)時(shí)網(wǎng)絡(luò)請(qǐng)求的加載策略,非核心/主要/高PV的功能相關(guān)的API,SDK、插件等沒有必要在啟動(dòng)時(shí)做加載緩存
(5)部分資源重復(fù)請(qǐng)求,建議信息緩存,常用信息只在第一次獲取,之后從緩存中取
(6)建議開發(fā)梳理無(wú)用但被執(zhí)行的老代碼,去掉無(wú)用但被執(zhí)行的老代碼

綜上,建議開發(fā)童鞋盡快投入做APP啟動(dòng)時(shí)性能改善和優(yōu)化,以提升行業(yè)相比競(jìng)品的競(jìng)爭(zhēng)力。

4、App端啟動(dòng)耗時(shí)排查方法及思路

4.1 排查方法:使用Traceview分析

TraceView 是 Android SDK 中內(nèi)置的1個(gè)工具,它可以加載 trace 文件,用圖形的情勢(shì)展現(xiàn)代碼的履行時(shí)間、次數(shù)及調(diào)用棧,便于我們分析。

(1)使用Android Studio工具DDMS

生成Traceview 進(jìn)行分析查看具體Trace期間各方法調(diào)用關(guān)系,調(diào)用次數(shù)以及耗時(shí)比例


ddms.png

(2)使用代碼生成 trace 文件

  Debug.startMethodTracing("shixintrace");   
 //開始 trace,保存文件到 "/sdcard/shixintrace.trace"
    // ...
    Debug.stopMethodTracing();    //結(jié)束

代碼很簡(jiǎn)單,當(dāng)你調(diào)用開始代碼的時(shí)候,系統(tǒng)會(huì)生產(chǎn) trace 文件,并且產(chǎn)生追蹤數(shù)據(jù),當(dāng)你調(diào)用結(jié)束代碼時(shí),會(huì)將追蹤數(shù)據(jù)寫入到 trace 文件中。
下1步使用 adb 命令將 trace 文件導(dǎo)出到電腦:

adb pull /sdcard/shixintrace.trace /tmp

使用代碼生成 trace 方式的好處是容易控制追蹤的開始和結(jié)束,缺點(diǎn)就是步驟略微多了一點(diǎn)。

(3)直接使用android studio生成trace文件

Android Studio 內(nèi)置的 Android Monitor 可以很方便的生成 trace 文件到電腦。
注意:此方法僅僅適用于下拉代碼到本地生成DEBUG測(cè)試包到手機(jī)進(jìn)行調(diào)試


monitor1.png
monitor2.png

分析指標(biāo):

不應(yīng)在Application以及Activity的生命周期回調(diào)中做任何費(fèi)時(shí)操作,具體指標(biāo)大概是你在onCreate,onResume,onStart等回調(diào)中所花費(fèi)的總時(shí)間最好不要超過400ms,否則用戶在桌面點(diǎn)擊你的應(yīng)用圖標(biāo)后,將感覺到明顯的卡頓。

4.2 開啟嚴(yán)苛模式(StrictMode)

檢查是否有主線程做了耗時(shí)操作: 開啟 嚴(yán)苛模式(StrictMode)

(1)StrictMode可以用于捕捉發(fā)生在應(yīng)用程序 主線程中耗時(shí)的磁盤、網(wǎng)絡(luò)訪問或函數(shù)調(diào)用,使主線程處理UI和動(dòng)畫在磁盤讀寫和網(wǎng)絡(luò)操作時(shí)變得更平滑,避免主線程被阻塞,導(dǎo)致ANR窗口的發(fā)生。

下面是啟用StrictMode的實(shí)例,可以在Application的OnCreate中添加,這樣就能在程序啟動(dòng)的最初一刻進(jìn)行監(jiān)控了。

private void setStrictMode() {
        if (Integer.valueOf(Build.VERSION.SDK) > 3) {
            Log.d(LOG_TAG, "Enabling StrictMode policy over Sample application");
            StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder()
                    .detectAll()    // 這里可以替換為.detectDiskReads().detectDiskWrites().detectNetwork()。
                                    // detectAll() 包括了磁盤讀寫和網(wǎng)絡(luò)I/O
                    .penaltyLog()   //打印logcat,當(dāng)然也可以定位到dropbox,通過文件保存相應(yīng)的log
                    .penaltyDeath()
                    .build());
            StrictMode.setVmPolicy(new StrictMode.VmPolicy.Builder()
                    .detectAll()
                    .penaltyLog()
                    .build());
        }
    }

(2)除了通過日志查看之外,我們也可以在開發(fā)者選項(xiàng)中開啟嚴(yán)格模式,開啟之后,如果主線程中有執(zhí)行時(shí)間長(zhǎng)的操作,屏幕則會(huì)閃爍,這是一個(gè)更加直接的方法。

4.3、通過抓包工具分析

可以通過抓包工具Charels、Fiddler等查看網(wǎng)絡(luò)請(qǐng)求加載了哪些資源,加載資源的順序、哪些資源重復(fù)加載、信息是否緩存

4.4、查看Logcat

通過adb輸出log信息,過濾日志查看APP啟動(dòng)時(shí)每個(gè)方法的大致耗時(shí)。

4.5、啟動(dòng)時(shí)間排查思路

對(duì)于App來說, 我們可以控制的啟動(dòng)時(shí)間線的點(diǎn)無(wú)外乎:

Application的onCreate
首屏Activity的渲染

而我們現(xiàn)在的App動(dòng)不動(dòng)集成了很多第三方服務(wù), 啟動(dòng)時(shí)需要檢查廣告, 注冊(cè)狀態(tài)等等一系列接口都是在Application的onCreate或是首屏的onCreate中做的.

5、啟動(dòng)時(shí)間耗時(shí)常見原因及優(yōu)化建議

5.1、 常見主要問題(持續(xù)補(bǔ)充ing)

  • 部分?jǐn)?shù)據(jù)庫(kù)及IO的操作發(fā)生在首屏Activity主線程;
  • Application中創(chuàng)建了線程池;
  • 啟動(dòng)時(shí)做密集沉重的初始化(Heavy app initialization);
  • Multidex的使用,也是拖慢啟動(dòng)速度的元兇;
  • UI存在過度繪制;
  • 首屏Activity網(wǎng)絡(luò)請(qǐng)求密集;
  • 非核心功能資源過早請(qǐng)求加載
  • 工作線程使用未設(shè)置優(yōu)先級(jí);
  • 信息未緩存,重復(fù)獲取同樣信息;
  • 流程問題:例如閃屏圖每次下載,當(dāng)次使用;
  • 執(zhí)行無(wú)用老代碼;
  • 執(zhí)行開發(fā)階段使用的代碼;
  • 執(zhí)行重復(fù)邏輯;
  • 調(diào)用三方SDK里或者Demo里的多余代碼;

5.2、建議:

  • 去掉無(wú)用但被執(zhí)行的老代碼;
  • 去掉開發(fā)階段使用但線上被執(zhí)行的代碼;
  • 去掉重復(fù)邏輯執(zhí)行代碼;
  • UI渲染優(yōu)化,去除重復(fù)繪制,減少UI重復(fù)繪制時(shí)間
  • 去掉調(diào)用三方SDK里或者Demo里的多余代碼;
  • 信息緩存,常用信息只在第一次獲取,之后從緩存中取;
  • 項(xiàng)目是多進(jìn)程架構(gòu),只在主進(jìn)程執(zhí)行Application的onCreate();
  • 根據(jù)優(yōu)先級(jí)的劃分,一些初始化工作能否將任務(wù)優(yōu)先級(jí)劃分成3個(gè)等級(jí),任務(wù)優(yōu)先級(jí)為2,3的,通過懶加載的方式在首頁(yè)渲染完成后進(jìn)行加載
  • 避免I/O操作、反序列化、網(wǎng)絡(luò)操作、布局嵌套等。

參考文獻(xiàn):
學(xué)習(xí)地址:
https://www.cnblogs.com/sunzn/p/3192231.html
http://www.wfuyu.com/technology/27625.html
http://blog.csdn.net/qq_16131393/article/details/51172488

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 228,238評(píng)論 6 531
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 98,430評(píng)論 3 415
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 176,134評(píng)論 0 373
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我,道長(zhǎng),這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,893評(píng)論 1 309
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 71,653評(píng)論 6 408
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 55,136評(píng)論 1 323
  • 那天,我揣著相機(jī)與錄音,去河邊找鬼。 笑死,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,212評(píng)論 3 441
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 42,372評(píng)論 0 288
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 48,888評(píng)論 1 334
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 40,738評(píng)論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 42,939評(píng)論 1 369
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,482評(píng)論 5 359
  • 正文 年R本政府宣布,位于F島的核電站,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 44,179評(píng)論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,588評(píng)論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,829評(píng)論 1 283
  • 我被黑心中介騙來泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 51,610評(píng)論 3 391
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 47,916評(píng)論 2 372

推薦閱讀更多精彩內(nèi)容