在前一篇文章中,我們討論了監(jiān)控app性能的重要性×陆現(xiàn)在挫剑,我們要告訴你具體如何去做到這一點(diǎn)。我們已經(jīng)和世界上幾個(gè)最受歡迎的app開發(fā)團(tuán)隊(duì)討論過了構(gòu)建流暢App的最佳實(shí)踐孙咪,團(tuán)隊(duì)包括WeChat、Yahoo News Digest應(yīng)用巡语。根據(jù)我們的經(jīng)驗(yàn)和與那些頂尖的開發(fā)者討論翎蹈,我們總結(jié)發(fā)現(xiàn)開發(fā)一個(gè)成功的App中最重要的實(shí)踐是建立一個(gè)性能優(yōu)化流程:
一直監(jiān)控app性能對(duì)當(dāng)你的app性能不佳時(shí)去監(jiān)測(cè)問題非常。一旦發(fā)現(xiàn)某個(gè)性能問題男公,一定要集中所有力量解決根本問題荤堪。檢測(cè)問題可能需要更多的措施和詳細(xì)的數(shù)據(jù)。偵測(cè)到問題的原因枢赔,僅僅對(duì)它進(jìn)行修復(fù)是不夠的澄阳,你還必須得重新評(píng)估你的app性能,驗(yàn)證你的修改已經(jīng)生效了糠爬。這就是更多的措施寇荧。
措施
有兩個(gè)性能指標(biāo)與用戶體驗(yàn)(UX)密切相關(guān)。首先执隧,我們來討論響應(yīng)時(shí)間:你的app響應(yīng)用戶操作需要多長(zhǎng)時(shí)間(比如啟動(dòng)app揩抡、打開新的文章、加載聯(lián)系人列表等)镀琉。理想情況下峦嗤,你的app響應(yīng)這些操作應(yīng)該非常快屋摔,這有助于提供更具吸引力的用戶體驗(yàn)烁设。
響應(yīng)時(shí)間的一個(gè)關(guān)鍵之一是啟動(dòng)時(shí)間。App的啟動(dòng)是給用戶第一體驗(yàn)感钓试,第一印象非常重要装黑。事實(shí)上,一份研究數(shù)據(jù)表明79%的用戶在刪除app之前會(huì)再次重試有問題的app一次或兩次弓熏。
這里有些來自NimbleDroid的建議恋谭,他擁有多年的軟件性能優(yōu)化經(jīng)驗(yàn)。
建議1:限制app的啟動(dòng)時(shí)間小于2秒
我們建議app的啟動(dòng)時(shí)間不超過2秒挽鞠,這是用戶期望的中等時(shí)間長(zhǎng)度疚颊。與Web性能類似狈孔,47%的用戶期望加載一個(gè)頁面的時(shí)間不超過2秒,并且移動(dòng)用戶的耐心更小材义,他們希望能快速順暢地使用均抽。
建議2:消除鴻方法
第二個(gè)重要指標(biāo)是平滑性。雖然具有很短的響應(yīng)時(shí)間非常棒其掂,但是響應(yīng)操作本身應(yīng)該足夠平滑油挥,將“停滯”最小化。用戶很善于發(fā)現(xiàn)停滯現(xiàn)象清寇,這意味著即使是很小的結(jié)巴也很能反應(yīng)出你的app的用戶體驗(yàn)感喘漏。
為了理解平滑性,你可以收集你的app每秒鐘的幀(FPS)和幀定時(shí)數(shù)據(jù)华烟。然而,需要注意的是這個(gè)數(shù)據(jù)并不能夠告訴你的app性能問題的原因持灰,也就是說它不能明確是哪個(gè)方法使得你的app出現(xiàn)停滯盔夜。
在Android中,UI線程(即主線程)是唯一可以更新UI的線程堤魁。為了維持60FPS的刷新頻率喂链,UI線程必須在大約16ms內(nèi)繪制完每個(gè)幀。如果在UI線程中妥泉,任何方法的調(diào)用時(shí)間超過這個(gè)時(shí)間椭微,那么app就必須失去一個(gè)幀,從而產(chǎn)生了一個(gè)異常的停滯盲链。更糟糕的是在這個(gè)時(shí)間期間蝇率,app不會(huì)相應(yīng)用戶操作,因?yàn)閁I線程卡住在一個(gè)方法調(diào)用中刽沾。
在實(shí)際開發(fā)中本慕,不能確定每個(gè)方法在UI線程中被調(diào)用的延時(shí)小于16ms。32ms可能會(huì)更加現(xiàn)實(shí)點(diǎn)侧漓,調(diào)用方法時(shí)間超過這個(gè)時(shí)間的方法稱為鴻方法锅尘,因?yàn)樗鼈円餫pp出現(xiàn)“卡頓”。去掉所有鴻方法非常有利于提高app的平滑性布蔗,從而為用戶提供更好的用戶體驗(yàn)藤违。
建議3:盡可能早的檢測(cè)
Okay!監(jiān)測(cè)與UX相關(guān)的指標(biāo)很重要纵揍,但是顿乒,監(jiān)測(cè)這些標(biāo)準(zhǔn)的頻率是多久才合適呢?每次build的時(shí)候骡男?每天build時(shí)淆游?每次發(fā)布前傍睹?發(fā)布后?你應(yīng)該衡量下什么時(shí)候來執(zhí)行檢測(cè)好些犹菱,越早跟蹤檢測(cè)軟件的標(biāo)準(zhǔn)拾稳,就會(huì)越早發(fā)現(xiàn)和處理性能問題。Yahoo團(tuán)隊(duì)安排每次發(fā)布版本之前腊脱,WeChat團(tuán)隊(duì)把它安排在app每天build的時(shí)候访得。
分析
建議4:了解常見性能問題
優(yōu)化軟件的關(guān)鍵是了解常見的性能問題并把它們從你的代碼消滅掉。在我們分析的下載量到達(dá)500萬的apps當(dāng)中陕凹,發(fā)現(xiàn)開發(fā)者往往是構(gòu)建的應(yīng)用在桌面運(yùn)行非澈芬郑快,但是在移動(dòng)端運(yùn)行就會(huì)明顯變慢杜耙。比如搜骡,ClassLoader.getResourceAsStream()方法加載一個(gè)3K的jar資源在MacBook Air上需要大約7ms,而這個(gè)操作在Nexus 7 2013上要耗時(shí)大約1700ms佑女。 這說明在Android中g(shù)etResourceAsStream的實(shí)現(xiàn)在它的第一次調(diào)用時(shí)執(zhí)行了大量額外的工作记靡,如索引APK文件中的所有資源、驗(yàn)證APK文件的權(quán)限团驱、解析它的manifest摸吠。像這樣的操作非常消耗CPU,從而使得app運(yùn)行明顯變慢嚎花,etResourceAsStream使得Walgreens app運(yùn)行變慢1.7秒寸痢。NimbleDroid 編譯了一系列方法來避免在你的Android app中使用它,可以從這里獲取紊选。
建議5:第三方SDK并不總會(huì)給你驚喜
有時(shí)候性能問題是由你使用的第三方SDK引起的啼止,并不是你自己的代碼問題。這樣的問題特別難偵測(cè)到丛楚。像非常流行的一Java時(shí)間庫(kù)org.joda.time族壳,可能你在以前的Java項(xiàng)目中使用過它,結(jié)果是它在你的app啟動(dòng)時(shí)僅僅創(chuàng)建一個(gè)org.joda.time.DateTime()對(duì)象就使得你的應(yīng)用明顯變慢趣些。這是因?yàn)閛rg.joda.time.DateTime() 使用了getResourceAsStream()去避免從APK文件中加載時(shí)間區(qū)仿荆。
優(yōu)化
修復(fù)運(yùn)行緩慢的代碼可以是一個(gè)噩夢(mèng)般的過程。有數(shù)百種可能使得app陷于卡頓坏平,發(fā)現(xiàn)app運(yùn)行緩慢的原因可能要耗時(shí)數(shù)個(gè)星期拢操。然而,有些常見修復(fù)準(zhǔn)則舶替。你要么使用更高效的數(shù)據(jù)集令境、算法、接口實(shí)現(xiàn)顾瞪,或調(diào)用的后臺(tái)線程不會(huì)使UI卡住舔庶。遵循上面的準(zhǔn)則抛蚁,你可使得你的app更高效,做出的產(chǎn)品會(huì)令人更喜歡惕橙。