案例研究

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

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

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

R8 优化器如何帮助 Reddit

R8 优化器是 Android 上性能优化的基础工具。它采取各种步骤来提高应用性能。让我们快速了解一下其中影响最大的步骤。

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

R8 优化的主要阶段

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

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

image.png

R8 如何提高 Reddit 的应用性能

该团队观察到冷启动速度提高了 40% ,“应用无响应”(ANR) 错误减少了 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 类型中将 minifyEnabledshrinkResources 设置为 true,以配置 app/build.gradle.kts 文件。

  android {

    ...

    buildTypes {

        release {

            isMinifyEnabled = true

            isShrinkResources = true

            proguardFiles(

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

                "keep-rules.pro",

            )

        }

    }

}

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

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

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

Reddit 在使用 R8 方面取得的成功为任何希望以较少的精力显著提高应用性能的开发团队提供了一个强有力的案例研究。技术改进与用户满意度随后提高之间的直接关联突显了性能优化的价值。

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

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

作者:

继续阅读