R8 構成アナライザを使用する

R8 Configuration Analyzer は、アプリの構成品質に関する詳細な分析情報を提供することで、R8 のパフォーマンス上のメリットを最大限に引き出すことを目的としたツールです。このツールを使用すると、最適化に利用できるコードベースの割合を示す主要な指標(圧縮スコア、最適化スコア、難読化スコア)をモニタリングして、R8 の最適化を追跡し、改善できます。サードパーティ ライブラリによって導入されたものを含め、広範な keep ルールや不要な keep ルールを特定することで、R8 ができるだけ多くのクラス、フィールド、メソッドを効果的に最適化できるように構成を調整できます。

レポートを生成する

AGP 9.3.0 以降では、専用のスタンドアロン Gradle タスクを使用して、または R8 ビルド中に自動的に R8 Configuration Analyzer レポートを生成できます。

スタンドアロン Gradle タスクを実行する(ローカルでの使用におすすめ)

keep ルールを積極的に反復処理する場合は、スタンドアロン Gradle タスクを使用して、APK や Bundle を完全にビルドせずに変更の影響をすばやく評価します。

./gradlew :app:analyzeReleaseR8Config

このタスクでは APK や Bundle の生成がスキップされるため、フィードバック ループが大幅に短縮されます。これにより、keep ルールが圧縮スコア、最適化スコア、難読化スコアに与える影響を迅速に分析し、すぐに調整できます。HTML レポートは app/build/reports/r8/r8-config-analyzer-release.html に生成されます。

通常のビルド中に自動的に生成する

完全な R8 リリースビルド(assembleRelease など)を実行すると、レポートは build/outputs/mapping/release/configanalyzer.html に自動的に生成されます。 通常のビルド中に自動的に出力が生成されないようにするには、次の Gradle プロパティを設定します。

android.experimental.r8.enableR8ConfigurationAnalyzer=false

AGP 9.2 以前の場合

AGP 9.2 以前の場合は、 com.android.tools.r8.dumpkeepradiushtmltodirectoryシステム プロパティを R8 でビルドを有効にして Gradle タスクを実行するときに設定します。

./gradlew assembleRelease \
    -Dcom.android.tools.r8.dumpkeepradiushtmltodirectory=<output_directory>

たとえば、次のコマンドを使用して、/tmp/r8analysis ディレクトリに HTML レポートを生成します。

# To create the /tmp/r8analysis folder.
mkdir -p /tmp/r8analysis

# To generate the report in the /tmp/r8analysis folder.
./gradlew assembleRelease \
    -Dcom.android.tools.r8.dumpkeepradiushtmltodirectory=/tmp/r8analysis

レポートを理解する

R8 Configuration Analyzer は、アプリの R8 構成と、各 keep ルールがアプリに与える影響に関する分析情報を提供します。これにより、R8 の最適化を最大限に活用して、アプリのパフォーマンスを向上させることができます。次のスコアを使用して、R8 で最適化できるコードベースの量を確認します。

レポートの概要セクションの例
図 1. レポートの概要セクションの例。

圧縮スコア

R8 はアプリを圧縮する際に、未使用のコードとリソースを特定して削除することで、アプリの全体的なサイズを縮小し、最終的なビルドをできるだけ軽量にします。圧縮スコアは、圧縮の対象となるクラス、フィールド、メソッドの割合を示します。たとえば、圧縮スコアが 66% の場合、R8 はコードベースの 66% で圧縮を実行できます。

最適化スコア

R8 は、メソッドのインライン化やクラスの統合などの最適化を実行し、アプリの起動とメモリを改善します。最適化スコアは、R8 の最適化の対象となるクラス、フィールド、メソッドの割合を示します。たとえば、最適化スコアが 66% の場合、R8 はコードベースの 66% でのみ最適化を実行できます。

難読化スコア

R8 は、クラス、フィールド、メソッドを短い名前に難読化することで、アプリのメタデータのフットプリントを削減してメモリを節約します。難読化スコアは、コードベース内で難読化できるコードの割合を測定します。

keep ルールを調整する

スコアを改善し、R8 の最適化を向上させるには、keep ルールを調整して、R8 がアプリを最適化するのを不必要に妨げないようにする必要があります。リフレクションを使用してアクセスされるクラス、メソッド、フィールドのみを保持する必要があります。

これを行うには、Keep Rule Analysis を使用します。

保持ルールの分析の例
図 2. keep ルール分析の例。

ルールの詳細な分析を表示するには、ルールをクリックして詳細画面を開きます。

保持ルールの分析の例
図 3. keep ルール分析の例。

keep ルールを調整する方法

keep ルールを調整して、アプリの R8 最適化の可能性を最大限に引き出すには、次の操作を行います。

  1. keep ルールごとに、R8 で最適化できないクラス、フィールド、メソッドの割合を Configuration Analyzer で確認します。これを使用して、多数のクラス、フィールド、メソッドの最適化を妨げている keep ルールを特定します。各 keep ルールによって妨げられている最適化プロパティも一覧表示されます。
  2. 多数のクラスの最適化を妨げている keep ルールがある場合は、keep ルールによって最適化が妨げられているクラス、フィールド、メソッドを確認して、リフレクションを使用して動的に呼び出されないアイテムがこのルールによって保持されているかどうかを確認する必要があります。
  3. 適切な keep オプションを選択し、ベスト プラクティスに沿って、必要な クラス、フィールド、メソッドのみをターゲットにすることで、keep ルールによってブロックされる最適化を減らします。
  4. keep ルールの影響を受けるクラス、フィールド、メソッドを対象とするテストを調査して実行し、keep ルールを調整します。

ライブラリの最適化を検査する

サードパーティ ライブラリを統合すると、R8 と連携するために独自のコンシューマー keep ルールが含まれることがよくあります。ライブラリの作成者は具体的な実装を予測できないため、必要以上に多くのクラス、フィールド、メソッドの最適化を妨げる、広範なルールを記述することがあります。 これにより、ライブラリの実際のランタイム実行とは関係のないアプリの部分が R8 によって最適化されない可能性があります。R8 Configuration Analyzer を使用すると、アプリの最適化に悪影響を与えるルールを導入しているライブラリを特定できます。

構成アナライザーを使用して、統合されたすべてのコンシューマー keep ルールの複合的な効果を検査します。サードパーティ ライブラリから提供される各 keep ルールの影響を分析することで、アプリで大量の最適化を妨げている特定のサードパーティ ライブラリを特定して追跡できます。

ライブラリを最適化する方法

サードパーティ ライブラリによって導入された keep ルールに対処するには、次の操作を行います。

  • ライブラリに広すぎるルールが含まれている場合は、レポートのデータを使用して、現在のルールがアプリの最適化スコアに与える影響を示すことをおすすめします。外部ライブラリの場合は、問題を報告する前に、ライブラリに既存のバグがないか確認してください。
  • 必要に応じて、特定のライブラリのルールを除外して、改善の可能性をテストできます。ルールを除外して 特定のライブラリからライブラリのルールをプロジェクトにインポートし、広範なルールを除外して、構成アナライザーを再実行して、サイズとパフォーマンスの潜在的な改善度を測定できます。

包含されたルール

複数の keep ルールが重複している場合、ルールの 1 つが不必要に多くの最適化を妨げている可能性があります。コードベースに 2 つの keep ルールがあるとします。

# Prevents optimization in the entire package
# Remove this to improve optimization
-keep class com.example.package.** { *; }

# Prevents optimization to the class inside the package
-keep class com.example.package.Myclass

パッケージ全体の最適化を妨げる最初の keep ルールは、最初の keep ルールによって保持されているパッケージ内のクラスをターゲットとする 2 番目の keep ルールを包含しています。keep ルールが重複している場合、1 つのルールが必要以上に多くの最適化をブロックする可能性があります。これらの重複するルールを調整することで、R8 の最適化を最大限に活用し、技術的負債を解消できます。このプロセスでは、R8 の最適化機能を最大限に活用しながら、必要なコードのみが保持されるように構成を効率化します。

レポートの概要セクションの例
図 4. レポート内の包含されたルールの例。

包含されたルールを最適化する

  1. R8 Configuration Analyzer を使用して、包含する keep ルールを見つけます。
  2. リフレクションに実際に依存しているコードベース内の正確なクラス、フィールド、メソッドを特定します。これらは keep ルールを使用して保持する必要があります。 これを把握することで、keep ルールを調整できます。
  3. 構成アナライザーを使用して、同じクラス、フィールド、メソッドをターゲットとする各ルールの影響を比較します。各 keep ルールによって妨げられる最適化の割合を使用して、広範な keep ルールと狭い keep ルールを特定できます。
    1. 狭いルールが正確に記述されている場合(リフレクションによってアクセスされる正確なメンバーまたはクラスのみを保持している場合)は、広範な keep ルールを削除します。これにより、パッケージの残りの部分で R8 の最適化が安全に有効になります。
    2. 広範なルールが適切なクラスをターゲットにしている場合は、広範なルールを保持し、狭いルールを削除します。狭いルールは冗長なクラッタです。 特定したクラス、フィールド、メソッドのみをターゲットにするように、広範なルールを調整してください。

変更を確認してテストする: 構成アナライザーを再実行して、競合が解決されていることを確認します。次に、リリースビルドをコンパイルし、変更をテストして、コードベースが期待どおりに動作することを確認します。

不要なルールを削除する

構成アナライザーを使用すると、コードベースを体系的に監査して、構成を煩雑にする古い keep ルールを特定して削除できます。R8 Configuration Analyzer では、不要なルールの主なソースが 2 つハイライト表示されます。

  • 未使用のルール: 現在のビルドでクラス、メソッド、フィールドが 1 つも一致しないルール。コードのリファクタリング、依存関係の削除後、または関連性のなくなったコピー&ペースト構成から残ることが多く、不必要な構成の複雑さを増しています。
  • 同一のルール: 同一の keep ルールとは、同じ クラス、フィールド、メソッドをターゲットとするルール、または同じ keep ルールファイル内または複数の keep ルールファイルにまたがる keep ルールの重複する宣言を意味します。

どちらのタイプのルールも構成にクラッタを追加し、保守とデバッグを困難にします。これらを特定することで、構成をクリーンアップできます。