解析ConstraintLayout的效能優勢
文 / Google 開發者計劃工程師 Takeshi Hagikura
自從在去年的 Google I/O 大會上釋出 ConstraintLayout 以來,我們一直不斷改進該佈局的穩定性,完善對佈局編輯器的支援。我們還針對 ConstraintLayout 增加了一些新功能,幫助您構建不同型別的佈局,例如引入鏈和按比例設定大小。
除了這些功能之外,使用 ConstraintLayout 還可以獲得一項顯著的效能優勢。在本文中,我們將向您介紹如何從這些效能改進中獲益。
Android 如何繪製檢視?
為了更好地理解 ConstraintLayout 的效能,我們先回過頭來看看 Android 如何繪製檢視。
當使用者將某個 Android 檢視作為焦點時,Android 框架會指示該檢視進行自我繪製。這個繪製過程包括 3 個階段:
1. 測量
系統自頂向下遍歷檢視樹,以確定每個 ViewGroup 和 View 元素應當有多大。在測量 ViewGroup 的同時也會測量其子物件。
2. 佈局
系統執行另一個自頂向下的遍歷操作,每個 ViewGroup 都根據測量階段中所確定的大小來確定其子物件的位置。
3. 繪製
系統再次執行一個自頂向下的遍歷操作。對於檢視樹中的每個物件,系統會為其建立一個 Canvas 物件,以便向 GPU 傳送一個繪製命令列表。這些命令包含系統在前面 2 個階段中確定的 ViewGroup 和 View 物件的大小和位置。
▲ 測量階段如何遍歷檢視樹的示例
繪製過程中的每個階段都需要對檢視樹執行一次自頂向下的遍歷操作。因此,檢視層次結構中嵌入(或巢狀)的檢視越多,裝置繪製檢視所需的時間和計算功耗也就越多。通過在 Android 應用佈局中保持扁平的層次結構,您可以為應用建立響應快速而靈敏的介面。
傳統佈局層次結構的開銷
請牢記上述解釋,下面我們來建立一個使用 LinearLayout 和 RelativeLayout 物件的傳統佈局層次結構。
▲ 佈局示例
假設我們想構建一個像上圖那樣的佈局。如果您使用傳統佈局來構建,XML 檔案會包含類似於下面這樣的元素層次結構(在本例中,我們忽略屬性):
儘管一般來說,這種型別的檢視層次結構都有改進的空間,但您幾乎必定還需要建立一個包含一些巢狀檢視的層次結構。
如前所述,巢狀的層次結構會給效能造成負面影響。我們使用 Android Studio 的 Systrace 工具來看看巢狀檢視對介面效能到底有何實際影響。我們通過程式設計方式針對每個 ViewGroup(ConstraintLayout 和 RelativeLayout)呼叫了測量和佈局階段並在執行測量和佈局呼叫期間觸發了 Systrace。以下命令可生成一個包含 20 秒間隔週期內發生的關鍵 Event 的概覽檔案,例如開銷巨大的測量/佈局階段:
有關如何使用 Systrace 的詳細資訊,請參閱使用 Systrace 分析介面效能指南:
https://developer.android.google.cn/studio/profile/systrace.html
Systrace 會自動突出顯示此佈局中的(大量)效能問題,並給出修復這些問題的建議。通過點選“Alerts”標籤,您會發現,繪製此檢視層次結構需要反覆執行 80 次的測量和佈局階段,開銷極為龐大!
觸發開銷如此龐大的測量和佈局階段當然很不理想,如此龐大的繪製 Activity 會導致使用者能夠覺察到丟幀的現象。我們可以得出這樣的結論:這種巢狀式層次結構和 RelativeLayout(會對其每個子物件重複測量兩次)的特性導致效能低下。
▲ 觀察 Systrace 針對使用 RelativeLayout 的佈局版本發出的提醒
您可以在我們的 GitHub 程式碼庫中檢視我們用來執行這些測量的完整程式碼:
https://github.com/googlesamples/android-constraint-layout-performance
ConstraintLayout 物件的優勢
如果您使用 ConstraintLayout 來構建相同的佈局,XML 檔案會包含類似於下面這樣的元素層次結構(再次忽略屬性):
如本例所示,現在,該佈局擁有一個完全扁平的層次結構。這是因為 ConstraintLayout 允許您構建複雜的佈局,而不必巢狀 View 和 ViewGroup 元素。
舉個例子,我們來看一下佈局中間的 TextView 和 EditText:
使用 RelativeLayout 時,您需要建立一個新的 ViewGroup 來垂直對齊 EditText 和 TextView:
通過改用 ConstraintLayout,您只需新增一個從 TextView 基線到 EditText 基線之間的約束,即可實現同樣的效果,而不必建立另一個 ViewGroup:
▲ EditText 和 TextView 之間的約束
在針對我們使用 ConstraintLayout 的佈局版本執行 Systrace 工具時,您會發現,同樣 20 秒間隔週期內執行的測量/佈局次數大大減少,開銷也隨之大大減少。這種效能的改進很有意義,現在,我們保持了扁平的檢視層次結構!
▲ 觀察 Systrace 針對使用 ConstraintLayout 的佈局版本發出的提醒
同樣值得一提的是,我們構建 ConstraintLayout 版本的佈局時僅僅使用了佈局編輯器,而不是手工編輯 XML。而要使用 RelativeLayout 來實現同樣的視覺效果,我們很可能必須手工編輯 XML。
測量效能差異
我們使用 Android 7.0(API 級別 24)中引入的 OnFrameMetricsAvailableListener 分析了 ConstraintLayout 和 RelativeLayout 這兩種型別的佈局所執行的每次測量和佈局操作所花費的時間。通過該類,您可以收集有關應用介面渲染的逐幀時間資訊。
通過呼叫以下程式碼,您可以開始記錄每個幀的介面操作:
在能夠獲取時間資訊之後,該應用觸發 frameMetricsAvailableListener() 回撥。我們對測量/佈局的效能感興趣,因此,我們在檢索實際幀的持續時間時呼叫了 FrameMetrics.LAYOUT_MEASURE_DURATION。
如需詳細瞭解 FrameMetrics 可以檢索的其他型別的持續時間資訊,請參閱 FrameMetricsAPI 參考:
https://developer.android.google.cn/reference/android/view/FrameMetrics.html
測量結果:ConstraintLayout 速度更快
我們的效能比較結果表明:ConstraintLayout 在測量/佈局階段的效能比 RelativeLayout大約高 40%:
▲ 測量/佈局(單位:毫秒,100 幀的平均值)
這些結果表明:ConstraintLayout 很可能比傳統佈局的效能更出色。不僅如此,ConstraintLayout 還具備其他一些功能,能夠幫助您構建複雜的高效能佈局。
有關詳情,請參閱使用 ConstraintLayout 構建快速響應的介面指南:
https://medium.com/google-developers/building-interfaces-with-constraintlayout-3958fa38a9f7
我們建議您在設計應用佈局時使用 ConstraintLayout。在過去,幾乎所有情形下,您都需要一個深度巢狀的佈局,因此,ConstraintLayout 應當成為您優化效能和易用性的不二之選。
附錄:測量環境 & 後續計劃
上述所有測量均在以下環境中執行:
裝置 - Nexus 5X
Android 版本 - 8.0
ConstraintLayout 版本 - 1.0.2
檢視開發者指南:
https://developer.android.google.cn/training/constraint-layout/index.html
API 參考文件:
https://developer.android.google.cn/reference/android/support/constraint/ConstraintLayout.html
媒體文章:
https://medium.com/google-developers/building-interfaces-with-constraintlayout-3958fa38a9f7
以完全理解 ConstraintLayout 能夠給您帶來什麼。再次感謝您,感謝自從我們的 Alpha 版 ConstraintLayout 釋出以來的幾個月裡提交反饋和問題的所有同仁。我們得以在今年早些時候釋出 ConstraintLayout 的 1.0 正式版,離不開您的支援,我們在此謹致以誠摯的謝意!我們將繼續改進 ConstraintLayout,請您繼續使用 Android Issue Tracker 向我們傳送反饋。
檢視全文及文中連結,請點選文末“閱讀原文”。
相關文章
- Android——ConstraintLayout的使用,優化佈局效能AndroidAI優化
- ConstraintLayout 全解析AI
- ClickHouse的查詢效能優勢
- ConstraintLayout 用法全解析AI
- 軟體效能測試的優勢
- 高效能渲染——詳解Html Canvas的優勢與效能HTMLCanvas
- Android效能優化全方面解析Android優化
- 資料庫優化效能解析資料庫優化
- 【效能優化】Oracle直方圖解析優化Oracle直方圖圖解
- 19個MySQL效能優化要點解析MySql優化
- Android新特性介紹,ConstraintLayout完全解析AndroidAI
- 正規表示式 vs. 字串處理:解析優勢與劣勢字串
- 深度解析Vmware磁碟優化,提高工作效能優化
- MySQL 效能優化的 9 種姿勢,面試再也不怕了!MySql優化面試
- Android 效能優化(十一)之正確的非同步姿勢Android優化非同步
- Go的優勢Go
- Docker的優勢Docker
- 【效能調優】Oracle AWR報告指標全解析Oracle指標
- 12種jQuery效能優化方法解析(常用 轉載)jQuery優化
- Oracle 【直接載入】全方位解析與效能優化Oracle優化
- 乾貨滿滿!深入解析增強分析的概念及其優勢
- 深度解析北京智慧養老服務平臺的特色與優勢
- 中科三方智慧雲解析PK普通解析四大優勢
- 雲伺服器是幹什麼的?其工作原理及優勢解析伺服器
- 製冷系統中蒸發式冷凝器的效能優勢DTZ
- ConstraintLayout的使用教程AI
- 【前端效能優化】vue效能優化前端優化Vue
- 從應用角度解析本地部署與SaaS哪個更有優勢?
- RAKsmart日本伺服器效能怎麼樣?有什麼優勢伺服器
- 解析Android應用在嵌入式醫療儀器裝置的優勢Android
- 雲解析的高防DNS技術有哪些優勢和作用?(國科雲)DNS
- Joomla優勢OOM
- 程式設計師的優勢和劣勢程式設計師
- 會 Python 的優勢Python
- IPv6的優勢
- TypeScript的三個優勢TypeScript
- Docker的優勢與不足Docker
- Flutter的效能優化Flutter優化