事例紹介

Reddit が R8 オプティマイザーを使用してパフォーマンスを大幅に改善した方法

所要時間: 4 分
Ben Weiss
デベロッパー リレーション エンジニア

モバイル アプリケーションが普及した現代において、シームレスなユーザー エクスペリエンスは単なる機能ではなく、不可欠な要素となっています。読み込み時間の遅さ、応答性の低いインターフェース、不安定さは、ユーザー エンゲージメントとユーザー維持の大きな障壁となる可能性があります。Reddit のエンジニアリング チームは、Android デベロッパー リレーションズ チームとの連携の中で、アプリ パフォーマンス スコアを使用してアプリを評価しました。パフォーマンスを評価した結果、大幅な改善の可能性があることがわかり、Android アプリ オプティマイザーである R8 の機能を最大限に活用するための手順を踏むことにしました。この取り組みに注力した結果、起動時間が大幅に短縮され、低速フレームやフリーズ フレーム、ANR が減少し、Google Play ストアでの評価が全体的に向上しました。このケーススタディでは、Reddit がこれらの目覚ましい成果をどのように達成したかについて説明します。

R8 オプティマイザーが Reddit にもたらしたメリット

R8 オプティマイザーは、Android でのパフォーマンス最適化の基礎となるツールです。アプリのパフォーマンスを改善するには、さまざまな手順が必要です。ここでは、最も効果的な手順を簡単に見ていきましょう。

  • ツリー シェイキングは、アプリのサイズを縮小するうえで最も重要なステップです。ここでは、アプリの依存関係とアプリ自体から未使用のコードが削除されます。
  • メソッドのインライン化では、メソッド呼び出しが実際のコードに置き換えられ、アプリのパフォーマンスが向上します。
  • クラスの統合などの戦略を適用して、コードをよりコンパクトにします。この時点では、ソースコードの人間による可読性ではなく、コンパイルされたコードを高速で動作させることが重要になります。そのため、インターフェースやクラス階層などの抽象化はここでは重要ではなく、削除されます。
  • 識別子の最小化では、クラス、フィールド、メソッドの名前が短く意味のない名前に変更されます。そのため、MyDataModel の代わりに a というクラスが作成されることがあります。
  • 不要なリソースの削除 では、xml ファイルやドローアブルなどの使用されていないリソースを削除して、アプリのサイズをさらに小さくします。
image.png

R8 最適化の主なステージ

ハードデータからユーザー満足度へ: 本番環境での成功を特定する

Reddit は、アプリの新バージョンをユーザーにリリースした直後に、パフォーマンスの結果が改善されたことを確認しました。Reddit は、Android VitalsCrashlytics を使用して、実際のユーザーが使用する実際のデバイスのパフォーマンス指標をキャプチャし、新しいリリースと以前のバージョンを比較することができました。

image.png

R8 が Reddit のアプリのパフォーマンスをどのように改善したか

チームは、コールド スタートアップの 40% の高速化「アプリケーション応答なし」(ANR)エラーの 30% の削減フレーム レンダリングの 25% の改善アプリサイズの 14% の削減を確認しました。

これらの機能強化は、ユーザー満足度を高めるうえで非常に重要です。起動が速いほど、待ち時間が短縮され、コンテンツにすばやくアクセスできます。ANR が減ると、アプリの安定性と信頼性が向上し、ユーザーの不満が軽減されます。フレーム レンダリングがスムーズになることで、UI のジャンクが解消され、スクロールやアニメーションが滑らかでレスポンシブになります。この技術的なプラスの影響は、ユーザーの感情にも明確に表れていました。

最適化の成功を示すユーザー満足度指標は、Google Play ストアで直接確認できました。R8 最適化バージョンのリリース後、ユーザーの感情とエンゲージメントに劇的かつポジティブな変化が見られました。

image.png

Drew Heavner: 「R8 の潜在能力を 2 週間以内に引き出す」

最も印象的だったのは、集中的な取り組みによってこれを達成したことです。この取り組みに携わった Reddit のスタッフ ソフトウェア エンジニアである Drew Heavner 氏は、R8 の潜在能力を最大限に引き出すための変更の実装に 2 週間もかからなかったと述べています。

パフォーマンスの向上を確認する: マクロベンチマークの詳細

Reddit のエンジニアリング チームと Google の Android デベロッパー リレーションズ チームは、実際の環境で大幅な改善が見られた後、詳細なベンチマークを実施して、改善効果を科学的に確認し、さらなる最適化を試しました。この分析のために、Reddit のエンジニアリング チームは、最適化されていないアプリと、R8 と 2 つの基本的なパフォーマンス最適化ツール(ベースライン プロファイル起動プロファイル)を適用したアプリの 2 つのバージョンを提供しました。

ベースライン プロファイルは、ジャストインタイム(JIT)コンパイルの手順をユーザー デバイスからデベロッパー マシンに効果的に移行します。生成された Ahead Of Time(AOT)コンパイル済みコードは、起動時間とレンダリングの問題の両方を軽減することが証明されています。

アプリがパッケージ化されると、d8 dexer はクラスとメソッドを取得し、アプリの classes.dex ファイルを構築します。ユーザーがアプリを開くと、これらの dex ファイルが読み込まれ、アプリが起動するまで順番に処理されます。スタートアップ プロファイルを指定すると、最初の classes.dex ファイルにどのクラスとメソッドをパックするかを d8 に伝えることができます。この構造により、アプリが読み込むファイルの数が減り、起動速度が向上します。

このフェーズでは、Jetpack Macrobenchmark が中心的なツールとなり、制御された環境でユーザー インタラクションを正確に測定できました。一般的なユーザー ジャーニーをシミュレートするために、UIAutomator API を使用して、アプリを開き、3 回スクロール ダウンしてから、スクロール アップするテストを作成しました。

最終的に、ベンチマークの作成に必要なのは次のコードだけでした。

  uiAutomator {

  startApp(REDDIT)

  repeat(3) {

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

  repeat(3) {

    onView {isScrollable }.fling(Direction.UP)

  }

}

ベンチマーク データは、フィールド観測を確認し、より深い分析情報を提供しました。完全に最適化されたアプリは、55% 早く起動し、ユーザーは 18% 早くブラウジングを開始できるようになりました。最適化されたアプリでは、ジャストインタイム(JIT)コンパイルの発生回数が 3 分の 2 削減され、JIT コンパイル時間が 3 分の 1 削減されました。フレーム レンダリングが改善され、ベンチマークされたユーザー ジャーニーで 19% 多くのフレームがレンダリングされるようになりました。最終的に、アプリのサイズは 3 分の 1 以上削減されました。

image.png

Reddit の全体的なパフォーマンスの改善

次のようなカスタム Macrobenchmark トレース セクション指標を使用して、JIT コンパイル時間を測定できます。

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

変革を支えるテクノロジー: R8

R8 をフルモードで有効にするには、リリース ビルドタイプで minifyEnabledshrinkResourcestrue に設定して、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 オプティマイザーの有効化、構成、トラブルシューティングに関する最新の公式ドキュメントとガイダンスをご覧ください。

作成者:

続きを読む