如何改善應用啓動性能 | Facebook 應用的經驗分享

作者 / Google 和 Facebook 團隊
撰稿 / Google Android 團隊的 Kateryna Semenova 和 Facebook 團隊的 Tim Trueman、Steven Harris、Subramanian Ramaswamy

簡介

縮短應用的啓動時間並非小事,我們必須深入瞭解其影響因素。今年,Google Android 團隊和 Facebook 應用團隊一直在合作研究這方面的量化指標,並共享優化方法,以改善應用啓動情況。Google Android 的公開文檔中包含了很多關於 應用啓動優化 的信息。這裏我們想進一步分享其在 Facebook 應用中的實踐情況,以及哪些因素有助於改善應用啓動性能。

現在,每個月有超過 29 億人使用 Facebook。Facebook 幫助人們構建社區,並讓世界更緊密地聯繫在一起。用戶會在這裏分享生活的瞬間,瞭解和討論正在發生的事情,建立和培養人際關係,共同合作以創造收入機會。

Facebook 應用開發者則致力於確保用戶享受最佳體驗,並讓應用在任意設備、任何國家/地區和不同網絡條件下都能流暢運行。Google Android 團隊和 Facebook 團隊精誠合作,在應用啓動時間的指標定義和最佳實踐上達成共識,並在這裏分享給大家。

從哪裏開始

首先自然是測量應用的啓動時間。您可藉此獲悉用戶啓動體驗的健康程度,追蹤啓動時間惡化的情況,並計算進行改進需要投入的資源量。歸根結底,您的啓動時間需要與用戶滿意度、參與度或用戶增長相關聯,以確定投入的優先次序。

Android 定義了兩個衡量應用啓動時間的指標: 完全顯示所用時間 (TTFD) 和 初步顯示所用時間(TTID)。雖然您可以進一步將其劃分爲冷/暖啓動時間,但本文不會解釋它們之間的區別,而 Facebook 的方法是,衡量和優化與應用交互的所有用戶所經歷的啓動時間 (有些是冷啓動,有些是暖啓動)。

完全顯示所用時間 (Time-To-Full-Display, TTFD)

TTFD 會記錄您的應用完成渲染並可供用戶交互和使用時所需的時間,可能包括顯示本地存儲或來自網絡上的內容所需的時間。如果網絡較慢,這可能會花費一段時間,並會視用戶的使用設備而有所差異。因此,我們有必要立即展示一些內容,讓用戶看到應用啓動的進程,而這就要提到 TTID 了……

初步顯示所用時間 (Time-To-Initial-Display, TTID)

TTID 會記錄您的應用顯示背景、導航、可快速加載的本地內容、加載較慢的本地或網絡內容的佔位塊所需要的時間。TTID 應該是用戶可以四處導航並前往其目標的所需時間。

不要改變太多: 有一件事需要注意,就是在 TTID 和 TTFD 之間應用內容的視覺變化問題,例如在頁面裏先展示的是已緩存的內容,然後在網絡內容加載完成後突然切換頁面內容。這種突然的變化可能會讓用戶感到不快和沮喪,所以請確保您的應用可在 TTID 期間顯示足夠有意義的內容,儘可能地向用戶展示其將在 TTFD 期間看到的內容。

達成用戶目標

用戶訪問您的應用是爲了獲取內容,這可能需要一段時間完成加載,而您希望應用可以儘快把這些內容呈現給他們。

Facebook 應用開發者專注於基於 完全顯示所用時間 (TTFD) 的指標,包含顯示所有內容和圖像,因爲這代表了用戶訪問應用的完整體驗。開發者想要知道,網絡加載內容和圖像是否花費了較長時間,或者加載失敗,以便讓團隊可以從頭到尾改善整個啓動體驗。

良好的 TTID 和 TTFD 目標應當是多少?

Facebook 將啓動時間指標設定爲他們認爲應用啓動耗時 "不佳" 的百分比,即任何 TTFD 超過 2.5 秒的啓動或啓動失敗的部分 (例如,圖像無法加載或應用崩潰)。Facebook 致力於通過改進時間超過 2.5 秒的啓動,使其擺脫 "不佳" 狀態,以及修復導致啓動失敗的問題,從而降低啓動時間 "不佳" 的比例。選擇 2.5 秒是因爲,研究表明,這對於 Facebook 用戶來說很重要。這也與 Web Vitals 爲網站建議的 最大內容繪製 (LCP) 指標相符。

與 TTID 相比,提供完整體驗,尤其是用網絡獲取最近的內容,會讓您的 TTFD 啓動指標看起來相當緩慢。而這其實是一件好事!它反映了用戶對您應用的真實體驗。您對此所做的改進,可能會像 Facebook 那樣,提高用戶的應用使用率以及對其性能的認可。

測量 TTFD 的棘手程度可能會視您的應用而異。如果太難,不妨從 初步顯示所用時間 (TTID) 着手。雖然由於佔位塊或圖像的存在可能會導致無法量化部分內容的加載性能,但這依然是一個着手點,畢竟這部分也是用戶日常與應用交互的內容 (雖然不是全部)。

檢測 TTID

在 Android 4.4 (API 級別 19) 及更高版本中,logcat 提供了 "Displayed" 值,用於記錄從啓動進程到完成在屏幕上繪製相應 Activity 第一幀所經過的時間。

報告的日誌行類似於以下示例:

ActivityManager: Displayed com.android.myexample/.StartupTiming: +3s534ms

檢測 TTFD

要檢測 TTFD,只需在您的所有內容都在屏幕上顯示後,在 Activity 中調用 reportFullyDrawn()。請確保包含替換佔位符的任何內容,以及您渲染的任何圖像 (務必計算圖像本身顯示的時間,而不僅是其佔位符顯示的時間)。在您調用 reportFullyDrawn() 後,就可以在 logcat 裏看到它:

ActivityManager: Fully drawn {package}/.MainActivity: +1s54ms

來自 Facebook 應用開發者的建議

多年來,Facebook 應用開發者一直在爲衆多設備、平臺以及國家/地區的數十億用戶優化應用。本節分享了 Facebook 應用開發者在優化應用啓動時運用的一些關鍵經驗。

  • 先理解,再優化 - 在定義了好的啓動指標後,您就應該用其檢測應用的具體表現,這有助於理解應用的啓動性能並設置改進優先級,爲您的用戶帶來更好的體驗。從量化檢測入手,一來可以證明存在提升空間,二來可以確定重點努力的方向,並且在開始優化後能看到具體的改進效果。

  • 首先修復崩潰 - 在您檢測啓動狀況之後,請確保應用確實可以啓動。啓動時的崩潰是最讓人沮喪的事情,也是讓用戶放棄您應用的最快方式,請優先判定和處理這些問題。

  • 切莫忘記功能可靠性 - 另外,不要忘記功能可靠性。您的應用是否能迅速展示一些內容,但卻未能加載所有內容,或者加載圖像的耗時過長?您的應用可能啓動得很快,但未能按用戶要求運行 (比如,點擊按鈕不起作用),這些因素都會惡化用戶體驗。

  • 以一致性爲目標 - 與具備一致性但啓動時間長於平均水平的性能表現相比,不一致的性能表現更令人沮喪。觀察啓動時間的長尾,查看是否存在緩解這些啓動緩慢情況的修復措施或方法。請務必查看您的離線和有損網絡啓動性能的啓動行爲。

  • 並行工作 - 大多數當代手機都有至少 4 個 CPU,所以有空間處理多任務!除非萬不得已,否則不要阻塞主線程。將 I/O 和非關鍵路徑移動到主線程之外運行。

  • 延遲執行 - 在實現了可靠且一致的啓動後,請查看您爲顯示首個可見畫面的內容所做的一切,是否有一些工作是不必要的?在應用啓動之後,請把與啓動體驗不直接相關的任何工作移除、延後、或者移到後臺 (但是注意觀察應用的響應能力,並將其作爲一個控制指標)。試着讓您應用的 onCreate() 儘量保持輕量。您還可使用 Jetpack App Startup 開發庫,以便在應用啓動時初始化組件。這樣做時,請確保仍然加載所有啓動活動所需的模塊,並且注意在延遲加載的模塊可用時不要造成閃爍。

  • 顯示進度,但是不要過多地改變界面 - 請不要在啓動期間過度改變要展示給用戶的內容。如果用戶嘗試點擊內容,結果它卻發生變化,並得到了錯誤的結果,這是十分令人沮喪的。這類似於 Web Vitals 中的 累積佈局偏移 (CLS) 概念。對於時長不定的網絡端加載,請略過啓動畫面,並顯示異步加載的佔位符。您可以考慮在這個內容區域使用不太顯眼的 動畫 來反映加載狀態。確保具體加載的內容結構和佔位結構儘可能地匹配,以便在內容加載完成後實現平滑過渡。

  • 緩存 - 當用戶第一次打開應用時,您可以爲一些界面元素展示加載指示器。在用戶下次訪問您的應用時,您可在加載更多最新內容的同時,顯示這些已緩存的內容。您是否曾在應用加載完成後,看到我們在 Facebook 的動態更新中展示從網絡獲取到的最新內容?如果可以,請將網絡加載過程從啓動中排除出去,這樣可以加快速度,並實現更一致的啓動性能體驗。但是,正如下一點所建議的那樣,顯示已緩存的內容並不總是最佳做法,因此,我們要衡量並找到對用戶更友好的要素。

  • 快慢結合 - 新穎,相關,但顯示速度稍慢的內容,比快速顯示的過時內容更好。直接向您的用戶展示最新的內容,比啓動超級迅速,但在啓動不久之後就得刷新內容要更有價值。您可以評估以下做法是否效果更好: 做出優化,以儘量快速地顯示最新內容,並設置超時時間,以在網絡較慢時顯示較舊的內容;在網絡離線時,直接顯示既有的內容。

  • 一致的會話開始界面 - 在您的應用長時間處於後臺後,您可能會發現,將用戶重置到您的主內容界面是很好的做法。應用可以在設備的內存中保留很長時間。

  • 查看內部工作原理 - 如果您 跟蹤 並切實查看了啓動期間執行的內容,或者乾脆使用調試器,您可能會有讓人驚喜的新發現!在充分了解了啓動的關鍵路徑後,您就可以高效地優化應用性能。在發現了具有最大提升空間的要素後,就在該方面做出投入。

  • 確保能輕鬆實現正確的結果 - 開發者有時會使用並非最優的模式和架構,因爲做事情的方法太多了。請放心大膽地整合您應用中使用的模式,然後加以優化,以便輕鬆選擇合適方法,從而完成任務並讓其高效運行。即時代碼執行 (eager code execution) 模式就是一個很好的例子: 如果您正在執行第一次全屏繪製後才需要出現的內容代碼,那麼性能表現肯定會遭受損害。您不妨採用延遲執行的模式,僅在啓動的關鍵路徑遭到阻塞時,再以即時執行方式運行代碼。

Google Android 團隊給出的建議

Google Android 團隊關於衡量和優化應用啓動的建議請查閱官方文檔 "應用啓動時間"。

本節總結了一些適用於所有 Android 應用開發者且與上述 Facebook 建議相關的要點。

  • TTID 和 TTFD 是應用啓動的重要指標。Google Android 會在 Play 管理中心 按照 TTID 對應用進行排名。TTFD 是 TTID 的母集,因此 TTID 的任何改進措施都同時適用於這兩個指標。

  • 調用 reportFullyDrawn() 來報告 TTFD,讓系統知道 Activity 已完成渲染。爲改善應用啓動速度,Android 系統會進行調整,以優先處理在調用 reportFullyDrawn() 之前發生的工作。在您的應用處於完全可用狀態時調用這個方法可以改善應用的啓動時間。每個應用都應該使用這個 API!切莫忘記用其衡量應用表現情況。

  • 用 Android Vitals 監控您應用的技術性能,有助於改善應用啓動體驗。通過 Play 管理中心,您可以查看各種數據以幫助您瞭解和改進應用的啓動時間等性能表現。

  • 我們知道,與在開發階段修復錯誤相比,生產環境中的修復成本要高得多。這點也同樣適用於性能方面。您可以藉助 Jetpack Macrobenchmark: Startup 設置您的應用,以在早期使用本地性能測試衡量應用啓動情況。

  • 正如我們上面討論的那樣,量化檢測是瞭解和優化啓動的關鍵。Android 提供 系統跟蹤 服務,可以幫助深入挖掘和診斷應用啓動問題。

  • 通過 Jetpack App Startup 開發庫,我們可以直接高效地在應用啓動時初始化組件。開發庫和應用的開發者都可以使用此庫來簡化啓動流程,並明確地設置初始化順序。您可以使用此庫設置在啓動期間的什麼時刻加載哪些組件。

  • 影響應用啓動的一個 典型問題 是在初始化時做了太多工作。比如,填充過大或複雜的佈局、阻止屏幕繪製、加載和解碼位圖、垃圾回收等。

總結

本文介紹了一些關鍵的啓動時間指標和優化最佳實踐,以改善啓動體驗,幫助提升 Facebook Android 應用的用戶參與度和使用率。本文還分享了 Google Android 團隊建議的指標、開發庫和工具。任何 Android 應用都可從本文分享的策略中受益。請大家動起手來,認真量化應用的啓動情況,併爲用戶打造快速且令人愉悅的應用啓動體驗!

歡迎您 點擊這裏 向我們提交反饋,或分享您喜歡的內容、發現的問題。您的反饋對我們非常重要,感謝您的支持!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章