使用 Jetpack Compose 提升 Play 商店的使用者體驗

Android開發者發表於2022-04-06
為了讓 Jetpack Compose 的使用體驗更上一層樓,以及瞭解大家對 Compose 開發、學習方面的內容需求,這裡誠邀您參與 Jetpack Compose 使用情況調研, 點選這裡 即刻參與調研。

作者 / Google Play 技術負責人 Andrew Flynn 和 Jon Boekenoogen

2020 年,Google Play 商店開發團隊管理層做出了一個重大決定: 改造整個 Play 商店技術棧。因為現有程式碼的歷史已經長達 10 多年,在無數的 Android 平臺版本釋出和功能更新的過程中產生了巨大的技術負債。我們需要新的框架,在不影響開發者的工作效率、使用者體驗或 Play 商店自身效能的同時,能夠支撐數百名工程師同時開展工作。

我們為此制定了一個長期路線圖,來更新商店內從網路層一直到畫素渲染的所有內容。在這之中,我們還想要採用現代的宣告式介面框架,以實現我們圍繞互動性和使用者滿意度的產品目標。在分析了各種選擇後,我們做出了 (在當時) 一個大膽的決定——使用當時還處於 Alpha 預覽階段的 Jetpack Compose

從那時起,Google Play 商店與 Jetpack Compose 團隊密切合作,釋出並完善了滿足我們特定需求的 Jetpack Compose 版本。本文將為您介紹我們的遷移方法以及在此過程中發現的挑戰和優勢,並分享一些對於有眾多貢獻者的應用選擇 Compose 的洞察。

優先考慮

當我們對新的介面渲染層使用 Jetpack Compose 時,需要優先考慮以下兩點:

  1. 開發者的工作效率 : Play 商店團隊有數百個工程師改進程式碼,因此開發起來應該很容易 (也很有趣)。
  2. 效能 : Play 商店會渲染大量媒體密集型內容,其中很多業務指標對延遲和卡頓十分敏感,所以我們需要確保它在所有裝置上表現良好,尤其是低記憶體硬體和 Android (Go 版本) 裝置。

開發者的工作效率

一年多來 ,我們一直在使用 Jetpack Compose 編寫使用者介面程式碼,也得益於 Jetpack Compose 讓介面開發變得更加簡單。

我們傾向於 編寫介面時使用更少的程式碼,有時甚至可以減少 50%。此項改進的實現得益於 Compose 是一個利用了 Kotlin 簡潔性的宣告式介面框架。自定義繪圖和佈局現在是簡單的函式呼叫,而不用再通過對檢視子類進行各種複寫。

以評分表格為例:

使用檢視類編寫,此表格包含:

  • 總共 3 個檢視類,其中 2 個需要自定義繪製圓角矩形和星形
  • 約 350 行 Java 程式碼,55 行 XML

使用 Compose 編寫,此表格包含:

  • 所有的 @Composable 函式都包含在同一檔案和語言中!
  • 約 210 行 Kotlin 程式碼

動畫

動畫因其簡單、富有表現力而成為 Compose 備受讚譽的一項功能。我們的團隊正在使用 Compose 構建動效功能,極大地提高了 Play 商店使用者的滿意度。藉助 Compose 的宣告性和動畫 API,編寫連續或並行動畫從未如此簡單。我們的團隊不再擔心關於動畫取消和回撥鏈的所有極端情況。Lottie 是一個流行的動畫庫,已經提供了易於使用的 Compose API。

您可以觀看《動畫成為 Compose 備受讚譽的一項功能》視訊瞭解更多有關使用 Compose 構建動畫的資訊。

現在您可能會想: 這一切聽起來都很棒,但提供檢視的庫依賴項呢?確實,並非所有的庫開發者都實現了基於 Compose 的 API,尤其是在我們首次遷移時。但是,Compose 通過其 ComposeView 和 AndroidView API 提供了 簡單的檢視互操作性。我們以這種方式成功地與 ExoPlayerYouTube Player 等流行庫整合。

效能

Play 商店和 Jetpack Compose 團隊密切合作,以確保 Compose 可以像檢視框架一樣快速執行並且沒有卡頓。由於需要把 Compose 打包在應用中 (而不是作為 Android 框架的一部分),這是一項艱鉅的任務。在螢幕上渲染單個介面元件很快,但是將整個 Compose 框架載入到應用記憶體中所用的端到端時間卻很長。

Play 商店採用 Compose 後最大的效能改進之一來自 基準配置檔案 的開發。雖然已經推出了一段時間的 雲配置檔案 可以幫助改善應用啟動時間,但是它們只適用於 API 28+,且對於更新節奏頻繁 (每週) 的應用效果不佳。為了解決這一問題,Play 商店和 Android 團隊合作開發了基準配置檔案 (Baseline Profiles): 開發者預定義打包好的、應用可以指定的一個配置檔案,它們隨您的應用提供,與雲配置檔案完全相容,並且可以在具體應用級別和庫級別進行定義 (適配 Compose 的開發者可免費使用此功能!)。通過推出基準配置檔案,Play 商店發現其搜尋結果頁的 初始頁面渲染時間減少了 40%。這是巨大的進步!

重複使用介面元件 是使 Compose 在渲染方面表現出色的 核心機制,尤其是在滾動情況下。Compose 會盡可能跳過已知可以跳過的可組合項的重組 (例如,它們是不可變的),但是如果所有引數滿足 @Stable 註釋要求,開發者也可以強制將可組合項設定為可跳過。Compose 編譯器還提供了一份 便捷指南,說明防止特定函式被跳過的原理。當在 Play 商店中建立在滾動情況下頻繁使用的大量重複使用介面元件時,我們發現不必要的重組會增加丟失的幀時間,從而導致卡頓。我們建立了一個 修飾符 (Modifier),以便在我們的除錯設定中輕鬆發現這些重組。通過將這些技術應用於我們的介面元件,我們能夠將卡頓減少 10-15%

△ 實際操作中的重組視覺化修飾符 (Modifiers)藍色 (無重組),綠色 (1 次重組)

△ 實際操作中的重組視覺化修飾符 (Modifiers)藍色 (無重組),綠色 (1 次重組)

為 Play 商店應用優化 Compose 的另一個關鍵是 為整個應用制定詳細的端到端的遷移策略。在最初的整合實驗中,我們遇到了雙棧問題: 在單個使用者會話中同時執行 Compose 和檢視類渲染非常佔用記憶體,尤其是在低端裝置上。當程式碼在同一頁面上執行時就會出現這種情況,當兩個不同的頁面 (例如,Play 商店主頁和搜尋結果頁) 各自位於不同的堆疊上時,也會出現這種情況。為了改善這種啟動延遲,我們 為頁面遷移到 Compose 的順序和時間安排 制定一個具體計劃,這是非常重要的。同時我們發現,在應用遷移到完全使用 Compose 進行渲染使用之前,對一些通用類進行一定的 "預熱" 是有助於提高記憶體效能的。

將 Compose 從 Android 框架中分離出來減少了我們團隊直接為 Jetpack Compose 做出貢獻的開銷,從而縮短了改進工作的週轉時間,使所有開發者受益。我們與 Jetpack Compose 團隊合作,推出 LazyList 專案型別快取 等功能,並快速進行輕量級修復,如 額外的物件分配

展望未來

Play 商店採用 Compose 後,提升了我們團隊開發者的幸福感,並 大大提高了程式碼質量和健康度。所有的全新 Play 商店功能都建立在此框架之上,且 Compose 有助於為應用實現更快的速度和更順暢的訪問。由於我們 Compose 遷移策略的性質,我們無法準確衡量 APK 大小 變化或構建速度等,但是我們看到的所有跡象都非常積極!

Compose 是 Android 介面開發的未來,也幫助 Play 商店實現了進一步的優化。歡迎您持續關注 我們瞭解最新內容。

相關文章