使用 Jetpack Compose 提升 Play 商店的用户体验

为了让 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 次重组)

为 Play 商店应用优化 Compose 的另一个关键是 为整个应用制定详细的端到端的迁移策略。在最初的集成实验中,我们遇到了双栈问题: 在单个用户会话中同时运行 Compose 和视图类渲染非常占用内存,尤其是在低端设备上。当代码在同一页面上运行时就会出现这种情况,当两个不同的页面 (例如,Play 商店主页和搜索结果页) 各自位于不同的堆栈上时,也会出现这种情况。为了改善这种启动延迟,我们 为页面迁移到 Compose 的顺序和时间安排 制定一个具体计划,这是非常重要的。同时我们发现,在应用迁移到完全使用 Compose 进行渲染使用之前,对一些通用类进行一定的 "预热" 是有助于提高内存性能的。

将 Compose 从 Android 框架中分离出来减少了我们团队直接为 Jetpack Compose 做出贡献的开销,从而缩短了改进工作的周转时间,使所有开发者受益。我们与 Jetpack Compose 团队合作,推出 LazyList 项目类型缓存 等功能,并快速进行轻量级修复,如 额外的对象分配

展望未来

Play 商店采用 Compose 后,提升了我们团队开发者的幸福感,并 大大提高了代码质量和健康度。所有的全新 Play 商店功能都建立在此框架之上,且 Compose 有助于为应用实现更快的速度和更顺畅的访问。由于我们 Compose 迁移策略的性质,我们无法准确衡量 APK 大小 变化或构建速度等,但是我们看到的所有迹象都非常积极!

Compose 是 Android 界面开发的未来,也帮助 Play 商店实现了进一步的优化。欢迎您持续关注 我们了解最新内容。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 214,951评论 6 497
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,606评论 3 389
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 160,601评论 0 350
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,478评论 1 288
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,565评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,587评论 1 293
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,590评论 3 414
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,337评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,785评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,096评论 2 330
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,273评论 1 344
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,935评论 5 339
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,578评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,199评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,440评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,163评论 2 366
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,133评论 2 352

推荐阅读更多精彩内容