案例研究

Reddit 如何使用 R8 优化工具大幅提升性能

阅读用时:4 分钟
Ben Weiss
开发者关系工程师

在当今的移动应用世界中,顺畅的用户体验不仅是一项功能,更是一项必需品。加载时间过长、界面无响应和不稳定性可能会严重阻碍用户互动和留存。在与 Android 开发者关系团队合作期间,Reddit 的工程团队使用 App Performance Score 评估了他们的应用。在评估了应用性能后,他们发现应用有很大的改进潜力,并决定采取措施来充分发挥 R8(Android 应用优化器)的强大功能。这项重点计划显著缩短了启动时间,减少了缓慢或冻结的帧和 ANR,并全面提升了 Play 商店评分。本案例研究将详细介绍 Reddit 如何取得这些令人瞩目的成果。

R8 优化器如何帮助 Reddit

R8 优化器是 Android 上进行性能优化的基础工具。需要采取各种步骤来提升应用性能。下面我们快速了解一下其中最有效的方法。

  • 摇树(优化)是缩减应用大小的最重要一步。在此阶段,系统会移除应用依赖项和应用本身中未使用的代码。
  • 方法内联会用实际代码替换方法调用,从而提高应用性能。
  • 应用类合并和其他策略,使代码更紧凑。此时,我们不再关注源代码的人工可读性,而是要让编译后的代码快速运行。因此,接口或类层次结构等抽象概念在这里并不重要,将被移除。
  • 标识符精简会将类、字段和方法的名称更改为更短、无意义的名称。因此,您最终可能会得到一个名为 a 的类,而不是 MyDataModel
  • 资源缩减 :移除未使用的资源(例如 XML 文件和可绘制对象),以进一步缩减应用大小。
image.png

R8 优化的主要阶段

从硬性数据到用户满意度:确定生产环境中的成功

在向用户推出新版应用后,Reddit 立即看到了性能方面的改进。通过使用 Android VitalsCrashlytics,Reddit 能够捕获实际用户在真实设备上的性能指标,从而将新版本与之前的版本进行比较。

image.png

R8 如何提升 Reddit 的应用性能

该团队发现,冷启动速度提升了 40% ,“应用无响应”错误减少了 30% ,帧渲染提升了 25% ,应用大小减少了 14%

这些增强功能对于提高用户满意度至关重要。启动速度更快意味着等待时间更短,可以更快地访问内容。减少 ANR 可让应用更稳定可靠,从而减少用户的不满。更流畅的帧渲染可消除界面卡顿,使滚动和动画效果流畅且响应迅速。这种积极的技术影响也清晰地体现在用户情绪中。

优化效果的用户满意度指标直接显示在 Google Play 商店中。在推出经过 R8 优化的版本后,该团队发现用户情绪和互动度发生了显著的积极转变。

image.png

Drew Heavner:“在不到 2 周的时间内,充分发挥 R8 的潜能”

最令人印象深刻的是,这项工作是通过集中精力完成的。Reddit 的软件工程师 Drew Heavner 参与了这项计划,他指出,实施这些变更以充分发挥 R8 的潜力不到两周

确认增益:使用宏基准进行深入分析

在观察到显著的实际改进后,Reddit 的工程团队和 Google 的 Android 开发者关系团队进行了详细的基准比较,以科学地确认这些增益,并尝试进一步优化。为了进行此分析,Reddit 工程团队提供了两个版本的应用:一个未进行优化,另一个应用了 R8 以及另外两款基础性能优化工具:基准配置文件启动配置文件

基准配置文件可有效地将即时 (JIT) 编译步骤从用户设备移至开发者机器。生成的预先 (AOT) 编译代码已证明可缩短启动时间并减少渲染问题。

应用打包时,d8 dexer 会获取类和方法,并构建应用的 classes.dex 文件。当用户打开应用时,系统会依次加载这些 dex 文件,直到应用可以启动为止。通过提供启动配置文件,您可以让 d8 知道要在第一个 classes.dex 文件中打包哪些类和方法。此结构可让应用加载更少的文件,从而提高启动速度。

Jetpack Macrobenchmark 是此阶段的核心工具,可在受控环境中精确测量用户互动。为了模拟典型的用户体验,他们使用 UIAutomator API 创建了一个测试,该测试会打开应用、向下滚动三次,然后再向上滚动。

最后,编写基准所需的全部内容如下:

uiAutomator {

  startApp(REDDIT)

  repeat(3) {

    onView { isScrollable }.fling(Direction.DOWN) }

  repeat(3) {

    onView {isScrollable }.fling(Direction.UP)

  }

}

基准数据证实了实地观测结果,并提供了更深入的洞见。完全优化的应用启动速度提高了 55% ,用户可以提前 18% 开始浏览。优化后的应用还显示,即时 (JIT) 编译次数减少了三分之二JIT 编译时间减少了三分之一。帧渲染得到改进,在基准用户体验历程中,渲染的帧数增加了 19%。最终,应用的大小缩减了超过三分之一。

image.png

Reddit 的整体性能改进

您可以使用如下所示的自定义 Macrobenchmark 轨迹部分指标来衡量 JIT 编译时间:

val jitCompilationMetric = TraceSectionMetric("JIT Compiling %", label = "JIT compilation")

启用转换背后的技术:R8

如需在完整模式下启用 R8,请在发布 build 类型中将 minifyEnabled 和 shrinkResources 设置为 true,从而配置 app/build.gradle.kts 文件。

android {

    ...

    buildTypes {

        release {

            isMinifyEnabled = true

            isShrinkResources = true

            proguardFiles(

                getDefaultProguardFile("proguard-android-optimize.txt"),

                "keep-rules.pro",

            )

        }

    }

}

此步骤之后必须进行全面的端到端测试,因为性能优化可能会导致意外行为,最好在用户发现之前就发现这些问题。

如本文前面部分所示,R8 会执行广泛的优化,以最大限度地提高性能优势。R8 会对代码进行大幅修改,包括重命名、移动和移除类、字段和方法。如果您发现这些修改会导致错误,则需要通过在保留规则中声明代码的哪些部分不应被 R8 修改,来指定这些部分。

在您的应用中效仿 Reddit 的做法

Reddit 在使用 R8 方面取得的成功为任何希望以极低的成本显著提升应用性能的开发团队提供了一个强有力的案例研究。技术改进与随之而来的用户满意度提升之间的直接相关性凸显了性能优化的价值。

通过遵循本案例研究中提出的蓝图(使用应用性能得分等工具来发现机会、充分发挥 R8 的优化潜力、监控实际数据,并使用基准来确认和加深了解),其他开发者也能获得类似的收益。

如需在自己的应用中开始使用 R8,请参阅有关启用、配置和排查 R8 优化器问题的最新更新的官方文档和指南

作者:

继续阅读