Jetpack Compose 可加快界面开发速度并改进 Android 开发。不过,请考虑将 Compose 添加到现有应用中可能会对应用的 APK 大小、build 和运行时性能等指标产生怎样的影响。
APK 大小和构建时间
本部分将通过查看 Sunflower 示例应用(该应用演示了将基于 View 的应用迁移到 Compose 的最佳实践)来介绍对 APK 大小和构建时间的影响。
APK 大小
向项目添加库会增加其 APK 大小。以下结果是针对每个项目的已缩小的发布版 APK(已启用资源和代码缩减)得出的,这些结果使用 R8 完全模式进行测量,并使用 APK 分析器进行测量。
| 仅限查看 | 混合使用 View 和 Compose | 仅限 Compose | |
|---|---|---|---|
| 下载大小 | 2,252 KB | 3,034 KB | 2,966 KB |
首次将 Compose 添加到 Sunflower 时,APK 大小从 2,252 KB 增加到 3,034 KB,增加了 782 KB。生成的 APK 包含使用 View 和 Compose 混合构建的界面。随着 Sunflower 添加了更多依赖项,出现这种增加是意料之中的。
相反,当 Sunflower 迁移到仅使用 Compose 的应用时,APK 大小从 3,034 KB 减少到 2,966 KB,减少了 68 KB。此降幅是由于移除了未使用的视图依赖项(例如 AppCompat 和 ConstraintLayout)所致。
构建时间
添加 Compose 会增加应用的构建时间,因为 Compose 编译器会处理应用中的可组合项。以下结果是使用独立 gradle-profiler 工具获得的,该工具会多次执行构建,以便获得 Sunflower 调试 build 持续时间的平均构建时间:
gradle-profiler --benchmark --project-dir . :app:assembleDebug
| 仅限查看 | 混合使用 View 和 Compose | 仅限 Compose | |
|---|---|---|---|
| 平均构建时间 | 299.47 毫秒 | 399.09 毫秒 | 342.16 毫秒 |
首次将 Compose 添加到 Sunflower 时,平均构建时间从 299 毫秒增加到 399 毫秒,增加了 100 毫秒。此时长是因为 Compose 编译器执行了额外的任务来转换项目中定义的 Compose 代码。
相反,在 Sunflower 完成向 Compose 的迁移后,平均构建时间降至 342 毫秒,减少了 57 毫秒。这种缩短可归因于多种因素,这些因素共同缩短了构建时间,例如移除数据绑定、将使用 kapt 的依赖项迁移到 KSP,以及将多个依赖项更新到最新版本。
摘要
采用 Compose 会有效增加应用的 APK 大小,还会因 Compose 代码的编译过程而提高应用的构建时间性能。不过,您需要权衡这些权衡取舍与 Compose 的优势,尤其是在采用 Compose 时开发者工作效率的提升。例如,Play 商店团队发现,编写界面所需的代码量大大减少,有时甚至减少了 50%,从而提高了代码的生产效率和可维护性。
如需阅读更多案例研究,请参阅为团队采用 Compose。
运行时性能
本部分涵盖与 Jetpack Compose 中的运行时性能相关的主题,可帮助您了解 Jetpack Compose 与 View 系统的性能比较情况,以及如何精准衡量性能。
智能重组
如果界面的某些部分无效,Compose 会尝试只重组需要更新的部分。如需详细了解此内容,请参阅可组合项的生命周期和 Jetpack Compose 阶段文档。
基准配置文件
基准配置文件是加快常见用户历程的绝佳方式。在应用中添加基准配置文件可以略过所包含代码路径的解译和即时 (JIT) 编译步骤,从而使应用首次启动时的代码执行速度即可提高约 30%。
Jetpack Compose 库包含自己的基准配置文件,当您在应用中使用 Compose 时,系统会自动进行这些优化。不过,这些优化只会影响 Compose 库中的代码路径,因此我们建议您向应用添加基准配置文件,以涵盖 Compose 之外的代码路径。
与 View 系统比较
与 View 系统相比,Jetpack Compose 有许多改进。以下部分介绍了这些改进。
对 View 进行了全方位扩展
在屏幕上绘制的每个 View(例如 TextView、Button 或 ImageView)都需要内存分配、显式状态跟踪和各种回调,才能支持所有用例。此外,自定义 View 所有者需要实现显式逻辑,以防止在非必要情况下(例如,重复数据处理)重新绘制。
Jetpack Compose 通过多种方式解决了此问题。Compose 中没有用于绘制视图的显式可更新对象。界面元素是简单的可组合函数,这些函数的信息以可重放的方式写入组合。这有助于将显式状态跟踪、内存分配以及回调缩减为仅对需要上述功能的可组合项执行,而不是对给定 View 类型的所有扩展都执行。
此外,Compose 还提供智能重组功能,如果您不需要进行更改,则会重放之前绘制的结果。
多次布局传递
传统 ViewGroup 在其测量和布局 API 中具有很强的表达能力,这使得它们容易进行多次布局传递。如果在视图层次结构中的特定嵌套点进行了多次布局传递,可能会导致工作量呈指数级增长。
Jetpack Compose 通过其 API 契约对所有布局可组合函数强制执行单次布局传递。这样一来,Compose 就能高效地处理较深的界面树。如果需要进行多次测量,Compose 具有内在测量功能。
View 启动性能
首次显示特定布局时,View 系统需要膨胀 XML 布局,由于布局是用 Kotlin 编写的,并且像应用的其余部分一样进行编译,因此 Jetpack Compose 中会保存此费用。
对 Compose 进行基准测试
在 Jetpack Compose 1.0 中,应用在 debug 和 release 模式下的性能存在显著差异。为使得出的时间结果具有代表性,在对应用进行性能分析时,请始终使用 release build(而非 debug)。
如需查看 Jetpack Compose 代码的性能,您可以使用 Jetpack Macrobenchmark 库。如需了解如何将其与 Jetpack Compose 搭配使用,请参阅 MacrobenchmarkSample 项目。
Jetpack Compose 团队还使用 Macrobenchmark 来捕获可能发生的任何回归问题。例如,请查看此 lazy 列的基准及其信息中心,以跟踪回归问题。
Compose 配置文件安装
由于 Jetpack Compose 是未捆绑库,因此它无法受益于 Zygote,后者会预加载 View 系统的界面工具包类和可绘制对象。Jetpack Compose 1.0 会利用配置文件安装来构建发布版本。借助配置文件安装程序,应用可以指定要在安装时进行预先 (AOT) 编译的关键代码。Compose 随附配置文件安装规则,可减少 Compose 应用的启动时间和卡顿。
为你推荐
- 注意:当 JavaScript 处于关闭状态时,系统会显示链接文字
- 其他注意事项
- 在 View 中使用 Compose
- 滚动