你好,歡迎來到IOS教程網

 Ios教程網 >> IOS編程開發 >> IOS開發基礎 >> Facebook iOS App如何優化啟動時間

Facebook iOS App如何優化啟動時間

編輯:IOS開發基礎

012.jpg

  • 本文由CocoaChina譯者小袋子(博客)翻譯

  • 原文:Optimizing Facebook for iOS start time


提高 Facebook 應用的性能已經成為 Facebook 持續關注的領域。因為我們相信一個高性能的應用能夠傳遞一種吸引人且令人愉悅的體驗。每個 Facebook 應用的用戶都必須做的一件事是啟動應用(我們特指這個動作為 ”應用啟動“)。因此,這是一個很好的優化目標。

穩定的指標

實現最好的性能度量標准和相應的目標,鼓舞我們專注於提升應用的品質,並且我們相信這將會產生很大的影響。度量必須易懂、經得起推敲,並且需要精確地捕捉到將要被優化的體驗。對基於性能的度量,我們已經發現在使用應用過程中,最好是使用那些被捕捉到感知的交互。理想情況下,這些度量應該和一個通過基礎設施的單一執行通道有一對一的聯系。對於應用程序的啟動,確定用於衡量的關鍵位置是一個挑戰。這需要采取幾次迭代去簡化我們的測量和移除邊界問題。

應用啟動是一個特別不固定的概念,因為現在存在很多種應用啟動的方式。應用可以在後台或者前台啟動,甚至可以在後台啟動,但是在完成初始化之前轉換為前台。你可以通過點擊一條通知或者通過一個 URL 打開應用。Facebook 應用甚至可以通過其他應用來打開,因為他們需要通過 Facebook 來實現第三方登錄。在現實場景中,主要的交互還是最直接的方式:你點擊桌面的應用圖標,然後跳轉啟動。因而,我們選擇這個作為應用啟動的入口。

當啟動入口明確之後,我們必須去計算出何時應用啟動是完成的。同樣地,我們觀察用戶的使用模式,發現用戶喜歡打開應用(首先跳轉到新聞摘要),然後等待摘要的加載。我們斷定“摘要完成加載”是應用啟動一個很好的終點。我們采取了一些微調使得這個終點契合用戶的使用情況。我們可以通過重復地觀察應用的啟動,圍繞度量標准來提高應用的性能。

一旦確定了我們認為有代表性的啟動入口和終點,我們把啟動問題分解成兩種類型:

  • 冷啟動。指的是當應用還沒准備好運行時,我們必須加載和構建整個應用。這包括設置屏幕底部的分欄菜單,確保用戶是否被合適地登錄,以及處理其他更多的事情。“引導”程序是在applicationDidFinishLaunching:withOptions:方法中開始的。

  • 熱啟動。指的是應用已經運行但是在後台被掛起(比如用戶點擊了 home 健),我們只需要知道在何時應用進入後台。在這種情況下,我們的應用通過 applicationWillEnterForeground: 接收到前台的事件,緊接著應用恢復。

我們決定主要優化冷啟動,主要有兩個原因。
首先,冷啟動其實是包括熱啟動的(冷啟動初始化應用並獲得摘要;熱啟動只獲得摘要),所以有更多的地方需要優化和微調。
其次,冷啟動需要做額外的初始化工作,所以相較而言更慢,導致需要更長的啟動等待時間。

優化冷啟動體驗

我們把冷啟動問題分解成三個階段,進而我們可以有針對性地解決。每個階段都有一些列變數和挑戰。

  • 請求時間:從應用啟動到摘要請求離開設備(譯者:應該是向服務器發送URL請求算結束時間)的時間。

  • 網絡時間:從摘要請求離開設備到服務器響應返回的時間。

  • 響應處理時間:從響應返回到新數據展示在屏幕的時間。

我們直觀上認為冷啟動性能主要被網絡請求和響應處理影響了。這個結論是由於我們假定我們在客戶端花的時間比較少,並且我們設法讓請求的獲取更加快速。然而,當我們用 instrument 去檢測時,我們發現數據非常出人意料。它展現出了完全不同的結果,我們發現摘要請求花了大部分時間。另外,響應的處理時間也非常短。因此,我們重新把優化的焦點放在初始化階段。

Feed請求發送的初始化

所以為什麼這個階段花費了那麼多時間呢?很多 iOS 應用並沒有這樣一個問題——他們在那個階段並沒有很多工作需要做,除了初始化視圖控制器和發送網絡請求。然而,對於 Facebook 來說,大部分時間被用來開始的時候去設置不同功能塊。下面是我們應用中的主要功能塊的流程概覽。 

12057214_1016971454990542_827610883_n.png

這看起來好像是很復雜的應用啟動設置。但需要重視的是,這些功能塊對於 Facebook 應用來說是非常重要的提升,可以提高應用體驗,並且使得工程師能夠在不同的應用規模下更快地開發。

正如我們所關注的這個流程,我們通過優化獨立的部分獲得了一些主要的成果。然而,由於未來支持新特性的初始化以及額外提供支持的基礎設施,這些成果會慢慢地抵消掉。這使得我們重新考慮如何去解決問題。但我們重新開始,我們認為這個階段的目標是簡單地發送摘要的網絡請求。但是為什麼摘要請求發出去得這麼慢?這是由於很多依賴被添加到摘要的初始化中了。然而,他們並不都是必要的 — 對於摘要請求來說,最少的需要一個有效的驗證 token 以及摘要光標(新聞摘要的位置)。因此,我們減少了摘要請求的依賴,讓它逐漸地更加接近應用的啟動。這允許應用的剩余部分在摘要響應的同時進行初始化。由於這些重構,我們獲得了顯著的收益。

網絡和服務器時間

根據我們在第一階段的經驗,我們繼續把這個階段分解成更小的部分。網絡請求/響應看起來像這樣: 

12056998_991399770918380_262846919_n.png

我們注意到,一旦請求正在排隊,發送請求出去之後就有一個時間間隔。這很好解釋 — 在冷啟動中,網絡連接並不是一個開放的、安全的 TCP 連接。一個連接的建立需要三次握手,平均為幾百毫秒。當摘要請求第一次發送時,無法避免要花掉這些時間。長遠來看,這可以通過緩存 SSL 證書來解決。但是再次強調,我們退回來的目的並不是為了發送 TCP 請求,而是為了從服務器通過任何可能的方式獲得請求信息。

我們提出了一個創造性的解決方案 — UDP 啟動。本質上,我們在通過 TCP 發送摘要請求時,先發送一個編碼過的包含摘要請求的 UDP 包到服務器。這樣做的目的是喚醒服務器更早地去獲取和緩存數據。當真正的摘要請求通過 TCP 到達時,服務器只需見到地從緩存內容中構造出響應,並發回客戶端。這個技術使得我們可以減少幾百毫秒的耗時。

當我們持續深入研究服務器端時,我們開始嘗試使用 層-取(story-fetching)策略。過去我們已經做了一批摘要請求的 3+7 層。原因很簡單:下載次數和被下載的層成正比。因此,把請求分割成兩塊,允許開始的三層先進來,其余的七個隨後進來。通過提升我們的基礎設施,我們已經能夠升級為 1+1+X 策略,這已經接近於流了。這樣就減少了服務器必須處理第一層的時間,並且能夠減少下載的時間,使得可以在最快的時間內與用戶交互。通過這樣的努力,這樣我們又減少了幾百毫秒的耗時。

Feed響應處理

正如在前面提到的那樣,我們以為在啟動時會在這裡花費大量的時間。但是這個想法被證明是錯誤的。更加使人好奇的是,我們注意到時間並沒有花在處理和加工層上面。時間被花在運行應用服務和競爭資源上面。我們注意到這是我們優化網絡和服務器時間的副作用,因為摘要請求返回得太早了。盡管大多數的服務是不重要的。因此,我們開發出一個簡單的機制去序列化這些工作直到應用完成啟動,並且使用先進先出的方式去執行。這樣可以用更少的連接去處理所有層,大大地減少了獲得響應和展示在屏幕之間的時間。

總結

很難理解我們在過去幾個月走了多遠。總之,在一對一的比較中,我們發現我們成功地優化了一秒多的耗時。

優化這個特殊的交互是一個長期的過程,需要建立一個穩定的度量,這個度量必須是易懂的、符合真實世界性能特征,此外要不斷地重新思考問題,以提出創新的解決方案。我們希望這可以幫助使用 Facebook 的人有更好的、令人愉悅的用戶體驗。

你也可以看看 Greg Moeck在 2015 年的演講。


  • 本文僅用於學習和交流目的,轉載請注明文章譯者、出處以及本文鏈接。 

  • 感謝博文視點對本期翻譯活動的支持。

博文logo-01.jpg

  1. 上一頁:
  2. 下一頁:
蘋果刷機越獄教程| IOS教程問題解答| IOS技巧綜合| IOS7技巧| IOS8教程
Copyright © Ios教程網 All Rights Reserved