关于android:相比-XML-Compose-性能到底怎么样

14次阅读

共计 3193 个字符,预计需要花费 8 分钟才能阅读完成。

前言

最近 Compose 曾经正式公布了 1.0 版本,这阐明谷歌认为 Compose 曾经能够用于正式生产环境了
那么相比传统的 XML,Compose 的性能到底怎么样呢?

本文次要从构建性能与运行时两个方面来剖析 Compose 的性能,数据次要来源于:Jetpack Compose — Before and after 与 Measuring Render Performance with Jetpack Compose , 想理解更多的同学能够间接点击查看

构建性能

Compose构建性能次要以 tivi 为例来进行阐明
Tivi是一个开源的电影 App,本来基于FragmentXML构建,同时还应用了 DataBinding 等应用了注解处理器的框架
起初迁徙到应用 Compose 构建UI, 迁徙过程分为两步

  1. 第一步:迁徙到 NavigationFragment, 每个 FragmentUI则由 Compose 构建
  2. 第二步:移除 Fragment,齐全基于Compose 实现UI

上面咱们就对 Pre-Compose,Fragments + Compose,Entirely Compose 三个阶段的性能进行剖析比照

APK体积

包体积是咱们常常关注的性能指标之一,咱们一起看下 3 个阶段的包体积比照



能够看出,TiviAPK 大小缩减了 46%,从 4.49MB 缩减到 2.39MB,同时办法数也缩小了17%

值得注意的是,在刚开始在利用中采纳 Compose 时,有时您会发现 APK 大小反而变大了
这是因为迁徙没有实现,老的依赖没有实现移除,而新的依赖曾经增加了,导致 APK 体积变大
而在我的项目齐全迁徙到 Compose 后,APK 大小会缩小,并且优于原始指标。

代码行数

咱们晓得在比拟软件我的项目时,代码行数并不是一个特地有用的统计数据,但它的确提供了对事物如何变动的一个察看指标。
咱们应用 cloc 工具来计算代码行数

cloc . --exclude-dir=build,.idea,schemas

后果如下图所示:

能够看出,在迁徙到 Compose 后,毫无意外的,XML代码行缩小了 76%
乏味的是 kotlin 代码同样缩小了,可能是因为咱们能够缩小很多模板代码,同时也能够移除之前写的一些 View Helper 代码

构建速度

随着我的项目的一直变大,构建速度是开发人员越来越关怀的一个指标。
在开始重构之前,咱们晓得,删除大量的注解处理器会有助于进步构建速度,但咱们不确定会有多少。

咱们运行以下命令 5 次,而后取平均值

./gradlew --profile --offline --rerun-tasks --max-workers=4 assembleDebug

后果如下


这里思考的是调试构建工夫,您在开发期间会更关注此工夫。

在迁徙到 Compose 前,Tivi 的均匀构建工夫为 108.71 秒。
在齐全迁徙到 Compose 后,均匀构建工夫缩短至 76.96 秒!构建工夫缩短了 29%
构建工夫能缩短这么多,当然不仅仅是 Compose 的功绩,在很大水平上受两个因素的影响:

  1. 一个是移除了应用注解处理器的 DataBindingEpoxy
  2. 另一个是 HiltAGP 7.0 中的运行速度更快。

运行时性能

下面咱们介绍了 Compose 在构建时的性能,上面来看下 Compose 在运行时渲染的性能怎么样

剖析前的筹备

应用 Compose 时,可能有多种影响性能的指标

  • 如果咱们齐全在 Compose 中构建 UI 会怎么?
  • 如果咱们对简单视图应用 Compose(例如用 LazyColumn 替换 RecyclerViews), 但根布局依然增加在XML
  • 如果咱们应用 Compose 替换页面中一个个元素,而不是整个页面,会怎么样?
  • 是否可调试和 R8 编译器对性能的影响有多大?

为了开始答复这些问题,咱们构建了一个简略的测试程序。
在第一个版本中,咱们增加了一个蕴含 50 个元素的列表(其中理论绘制了大概 12 个)。该列表包含一个单选按钮和一些随机文本。


为了测试各种选项的影响,咱们增加以下 4 种配置, 以下 4 种都是开启了 R8 同时敞开了debug

  1. 纯 Compose
  2. 一个 XML 中,只带有一个 ComposeView, 具体布局写在Compose
  3. XML中只蕴含一个 RecyclerView,然而RecyclerView 的每一项是一个ComposeView
  4. XML

同时为了测试 build type 对性能的影响,也增加了以下 3 种配置

  1. Compose, 敞开R8 并关上debug
  2. Compose, 敞开R8 并敞开debug
  3. XML,敞开R8 并关上debug

如何定义性能?

Compose运行时性能,咱们个别了解的就是页面启动到用户看到内容的工夫
因而上面几个机会对咱们比拟重要

  1. Activity启动工夫, 即onCreate
  2. Activity启动实现工夫,即onResume
  3. Activity渲染绘制实现工夫,即用户看到内容的工夫

onCreateonResume 的机会很容易把握,重写零碎办法即可,但如何取得 Activity 齐全绘制的工夫呢?
咱们能够给页面根 View 增加一个 ViewTreeObserver, 而后记录最初一次onDraw 调用的工夫

应用 Profile 查看下面说的过程,如下别离为应用 XML 渲染与应用 Compose 渲染的具体过程, 即从 OnCreate 到调用最初一次 onDraw 的过程


渲染性能剖析

晓得了如何定义性能,咱们就能够开始测试了

  1. 每次测试都在几台设施上运行,包含最近的旗舰、没有 Google Play 服务的设施和一些便宜手机。
  2. 每次测试在同一台手机上都会运行 10 次,因而咱们不仅能够获取首次渲染工夫,也能够获取二次渲染工夫
  3. 测试 Compose 版本为 1.0.0

咱们依据下面定义的配置,反复跑了屡次,失去了一些数据,感兴趣的同学能够间接查看所有数据


剖析后果如上图所示,咱们能够得出一些论断

  • R8和是否可调试对 Jetpack Compose 渲染工夫产生了显着影响。在每次试验中,禁用 R8 和启用可调试性的构建所破费的工夫是没有它们的构建的两倍多。在咱们最慢的设施上,R8 将渲染速度放慢了半秒以上,而禁用 debug 又使渲染速度放慢了半秒。
  • XML中只蕴含一个 ComposeView 的渲染工夫,跟纯 Compose 的耗时差不多
  • RecyclerView中蕴含多个 ComposeView 是最慢的。这并不奇怪, 在 XML 中应用 ComposeView 是有老本的,所以页面中应用的 ComposeView 越少越好。
  • XML在出现方面比 Compose 更快。没有方法解决这个问题,在每种状况下,Compose 的渲染工夫比 XML 长约 33%。
  • 第一次启动总是比后续启动破费更长的工夫来渲染。如果您查看残缺的数据,第一个页面的渲染工夫简直是后续的两倍。

比拟让我诧异的是, 只管 Compose 没有了将 XML 转化成 ViewIO操作,测量过程也因为固有个性测量进步了测量效率,但性能依然比 XML 要差
不过, 依据 Leland Richardson 的说法,当从 Google Play 装置应用程序时,因为捆绑的 AOT 编译,Compose 在启动时渲染会更快,从而进一步放大了与 XML 的差距

总结

通过上面对 Compose 性能方面的剖析,总结如下

  1. 如果齐全迁徙到Compose,在包体积,代码行数,编译速度等方面应该会有比拟大的改善
  2. 如果处于迁徙中的阶段,可能因为旧的依赖没有去除,而曾经引入了新的依赖,反而导致包体积等变大
  3. 只管没有了 XML 转换的 IO 操作,测量过程也通过固有个性测量进行了优化,Compose的渲染性能比起 XML 依然有肯定差距
  4. 只管目前 Compose 在性能方面略有欠缺 (在大多数设施上仅超过一两帧),但因为其在开发人员生产力、代码重用和申明式UI 的弱小个性等方面的劣势,Compose仍被举荐应用

视频:Android 开发中高级进阶:JetPack Compse 开发利用实战

原文:https://juejin.cn/post/7008522702835154980

正文完
 0