Facebook iOS新版開發手記:兩倍速度的背後

發表於2012-08-30

新浪科技)Facebook上週釋出了新版iOS應用,號稱速度提升兩倍。Facebook工程師Jonathan Dan在Facebook官方頁面中撰文,介紹了新版iOS應用、Facebook iOS應用的發展歷程以及開發思路。《創事記》特選取此文編譯,供移動應用開發者參考。

我們今天釋出了新版iOS應用,速度更快、更可靠、更易用。這款新應用標誌著Facebook移動產品開發方式的轉型,即深耕不同平臺。為了便於你們理解這一轉型,讓我們回顧移動版Facebook的發展歷程。

起步階段的Three20框架:技術過時首次棄用

早期的iPhone版Facebook誕生於iPhone的起步階段,當時還沒有iPad,而系統也不叫iOS。在早期版本中,我們開發了名為Three20的開源框架,其中包括當時系統尚未提供的元件庫。

在隨後幾年中,Three20成為iOS社群最流行的開源專案之一,幫我們解決了很多問題。然而隨著技術的發展,Three20逐漸顯得過時。其功能越來越複雜,對入門者來說上手變難。另一方面,隨著iOS核心的迅速發展,Three20的一些功能也顯得沒有太大用途。因此,最新版iOS應用是我們這麼多年來首次沒有使用Three20框架。

HTML5的發展:跨平臺快速迭代

隨著過去幾年移動裝置的發展,我們最需要解決的問題是,無論你用什麼裝置、平臺、運營商網路,甚至無論你在哪裡,都應當獲得不錯的移動體驗。為了支援數千款手機和多個移動平臺,我們利用HTML5技術去開發移動版Facebook,並向包括iOS在內的多個平臺釋出。

利用HTML5,我們只要進行一次開發,就可以向多個平臺釋出產品。這樣做使我們能覆蓋儘可能多的使用者,也使Facebook移動業務發展到了當前的規模。實際上,我們選擇HTML5不僅是因為可以跨平臺使用一套程式碼,也是由於這樣做有利於快速迭代,在不釋出新版本的情況下測試新功能。

基於這一網頁技術,我們為5億Facebook移動使用者提供服務,並支援了7000多款裝置。然而我們意識到,對iOS這樣的平臺來說,人們會希望更快、更可靠的體驗,而這正是我們iOS應用的不足之處。我們已經普及了移動服務,現在需要深耕服務。因此,我們從頭開始重寫了Facebook的iOS應用,專注於質量,並充分利用iOS系統自身這些年來的發展。

一切為了速度:耗時任務扔後臺

開發原生iOS應用帶來了一個顯而易見的好處,就是應用的速度。在新版iOS應用中,動態彙總的滾動明顯更流暢,而具體實現方式則是對處理任務的系統資源進行更好的排程。例如在iOS中,主執行緒驅動使用者介面,處理觸控事件,因此如果在主執行緒中處理太多工,那麼應用就會變慢。為了解決這一問題,我們儘量在後臺處理對計算資源要求較高的任務,包括所有網路活動、JSON分析、NSManagedObject物件建立以及存檔等。

可以再舉另一個例子。我們使用Core Text顯示字串,但排版計算很快成為一個瓶頸。在新版iOS應用中,當我們下載新內容時,我們以非同步方式計算字串大小,快取在CTFramesetters中,當需要在UITableView中顯示時再利用這些計算結果。

在iOS中啟動Facebook應用時,你會想看見動態彙總,而不是正在載入的下拉選單。因此,為了提供最好的體驗,我們在應用啟動時立即顯示此前快取的內容。不過這帶來了新問題:如果你的動態彙總中內容太多,那麼UITableView將呼叫一個委託函式tableView:heightForRowAtIndexPath: ,對每條內容進行處理,以計算滾動條長度。這將導致應用需要從磁碟中載入所有內容,對整個內容排版進行計算,隨後返回所有內容的高度總和。這意味著,當動態彙總中內容過多時,啟動速度會變得更慢。

解決這一問題的方法分為兩部分。首先,當我們初始化非同步排版計算時,我們在Core Data中儲存了內容的高度。通過這樣做,我們避免了在tableView:heightForRowAtIndexPath:函式中計算排版資訊。其次,我們將“內容”的模式物件進行分解,在應用啟動時只會從磁碟讀取內容的高度資訊,隨後才讀取其他資訊。而其他的排版計算均通過非同步方式來完成。

通過以上這些方式,我們在螢幕滾動時實現了更高的幀率,並使應用保持響應。

Facebook iOS新版開發手記:兩倍速度的背後

 

新的基礎:Messenger及其他

開發人員總是避不開一些限制,一些是技術上的,一些是設計上的,一些則是由產品需求引起的。當我們重新開發iOS應用時,一款新的原生應用Facebook Messenger正越來越流行。為此,我們需要完全整合Messenger的底層架構和使用者介面,並充分利用Messenger團隊此前已經過充分測試的程式碼。當點選iOS應用中“Messages”圖示時,執行的程式碼將與Facebook Messenger應用完全一致。

為了實現這一目標,我們按模組來搭建系統。當你在左側導航選單中點選書籤時,模組提供的視覺效果將得以顯示。動態彙總、Messages、Friends,這些都是模組。模組也會說明相互之間的依賴關係。例如,我們使用MQTT去更新通知、訊息和書籤。在應用啟動時,應用會遍歷依賴關係圖,確保在通知功能啟動前先啟動MQTT服務。在增加新功能時,模組系統也將確保應用在正確時間、正確位置啟動。

儘管模組系統部分解決了問題,但Messenger也不可能簡單地以新核心取代當前程式碼。新版iOS應用中的認證系統以及Messenger應用的執行方式共享了同一介面的物件。用Objective-C的語言來說,就是“遵循了同樣的協議”。通過與Messenger團隊的合作,我們開發了依賴注入系統,向Messenger程式碼提供了用於實時驗證的物件。當作為一款獨立應用時,Messenger程式碼以自己的方式處理這些物件。當作為Facebook應用的一個模組時,將採取不同的處理方式。在程式碼中加入這些物件是一個聰明的做法。

未來計劃:不必更新應用的升級

目前,動態彙總中的內容都有頁面頭,其中包括內容預覽圖、時間戳、訊息、照片、視訊,以及“贊”和“評論”按鈕。這通過HTML5很容易實現,並且可以快速更新設計,例如使用者何時更新了動態彙總,使照片尺寸更大等。不過,動態彙總也在持續發展,當我們增加新功能時,採用Objective-C的方法將帶來新的挑戰。

為了解決這一問題,我們採用不同的方式去增加新功能,同時不必升級整個應用,這就是“回退渲染器”(fallback機制)。當動態彙總團隊設計了一種新的內容形式時,iOS應用將下載到一些無法識別的內容。當我們檢測到這種內容時,我們將使用回退渲染器,以應用可識別的格式顯示新內容中的相關資訊。與此同時,我們開發了新的定製渲染器,在下一次應用升級時釋出。對於應用中可能經常更新的部分,我們仍將繼續使用HTML5程式碼,這樣我們可以在伺服器端推送升級,而使用者不必下載新版本應用。

最後做個廣告:你口袋中最好的Facebook體驗

開發原生iOS應用使我們有能力保證應用的速度、可靠性和功能。無論使用時間是30秒,還是乘火車旅行,我們都希望你能有快速而滿意的體驗。我們認為,移動是Facebook最好的平臺,並希望在任何時間任何地點通過這一平臺提供最好的Facebook體驗。新版iOS應用只是我們其中一步。

 

相關文章