Jetpack Compose 可加快界面开发,并改进 Android 开发。不过,请考虑向现有应用添加 Compose 会对应用的 APK 大小、构建性能和运行时性能等指标产生怎样的影响。
APK 大小和构建时间
本部分将通过查看 Sunflower 示例应用(一款演示如何将基于 View 的应用迁移到 Compose 的应用)来介绍对 APK 大小和 build 时间的影响。
APK 大小
将库添加到项目中会增加 APK 大小。以下是 Compose 对每个项目的缩减版 APK 的影响,这些项目启用了资源和代码缩减功能,使用 R8 完整模式。影响的结果使用 APK 分析器进行衡量。
仅限观看 | 混合使用 View 和 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 的调试构建时长的平均构建时间:
gradle-profiler --benchmark --project-dir . :app:assembleDebug
仅限观看 | 混合使用 View 和 Compose | 仅限撰写模式 | |
---|---|---|---|
平均构建时间 | 299.47 毫秒 | 399.09 毫秒 | 342.16 毫秒 |
首次向 Sunflower 添加 Compose 时,平均 build 时间从 299 毫秒增加到 399 毫秒,增加了 100 毫秒。此时长是因为 Compose 编译器执行了额外的任务来转换项目中定义的 Compose 代码。
相反,在 Sunflower 完成向 Compose 的迁移后,平均构建时间缩短至 342 毫秒,减少了 57 毫秒。这种缩短可归因于多种因素,这些因素共同缩短了 build 时间,例如移除数据绑定、将使用 kapt 的依赖项迁移到 KSP,以及将多个依赖项更新到最新版本。
摘要
采用 Compose 会有效增加应用的 APK 大小,还会因 Compose 代码的编译过程而提高应用的构建时间性能。不过,您需要权衡这些权衡取舍与 Compose 的优势,尤其是在采用 Compose 时开发者工作效率的提升。例如,Play 商店团队发现,编写界面所需的代码量大大减少,有时甚至减少了 50%,从而提高了代码的开发效率和可维护性。
如需阅读更多案例研究,请参阅为团队采用 Compose。
运行时性能
本部分介绍了与 Jetpack Compose 中的运行时性能相关的主题,以帮助您了解与 View 系统相比,Jetpack Compose 的性能如何,以及如何衡量性能。
智能重组
如果界面的某些部分无效,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 和布局 API 方面有诸多表现形式,因此很容易导致发生多次布局传递。如果在视图层次结构中的特定嵌套点进行了多次布局传递,可能会导致工作量呈指数级增长。
Jetpack Compose 通过其 API 协定为所有布局可组合项强制执行单次布局传递。这使 Compose 能够高效地处理较深的界面树。如果需要进行多次测量,Compose 具有固有特性测量。
View 启动性能
首次显示特定布局时,View 系统需要膨胀 XML 布局,Jetpack Compose 则节省了此开销,因为布局是使用 Kotlin 编写的,并像应用的其余部分一样进行编译。
对 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 利用了 release build 的配置文件安装。ProfileInstaller 可让应用指定要在安装时进行预先 (AOT) 编译的关键代码。Compose 随附配置文件安装规则,可减少 Compose 应用的启动时间和卡顿。
为您推荐
- 注意:当 JavaScript 处于关闭状态时,系统会显示链接文字
- 其他注意事项
- 在 View 中使用 Compose
- 滚动