R8 でアプリの最適化を有効にする

ユーザー エクスペリエンスを向上させるには、アプリをできるだけ小さく、高速になるように最適化する必要があります。R8 というアプリ オプティマイザは、未使用のコードやリソースを削除し、コードを書き換えてランタイム パフォーマンスを最適化することで、アプリを効率化します。ユーザーにとって、これは次のようなメリットがあります。

  • 起動時間を短縮
  • メモリ使用量の削減
  • レンダリングとランタイム パフォーマンスの向上
  • ANR の減少

R8 の最適化の概要

R8 は、複数フェーズのプロセスを使用して、アプリのサイズと速度を最適化します。主なオペレーションは次のとおりです。

  • コード圧縮(ツリー シェイキングとも呼ばれます): R8 は、アプリとそのライブラリの依存関係から 到達不能なコードを特定して削除します。R8 は、アプリのエントリ ポイント(マニフェストで定義された ActivitiesServices など)を分析して、参照されるコードのグラフを作成し、参照されないものをすべて削除します。

  • 論理的な最適化: R8 は、実行 効率を向上させ、オーバーヘッドを削減するためにコードを書き換えます。主な手法は次のとおりです。

    • メソッドのインライン化: R8 は、メソッド呼び出しサイトを呼び出されたメソッドの実際の本文 に置き換えます。これにより、関数呼び出しのオーバーヘッドが解消され、R8 でさらに最適化を行うことができます。

    • クラスのマージ: R8 は、クラスとインターフェースのセットを 1 つのクラスに結合します。これにより、アプリ内のクラスの数が減り、メモリ負荷が軽減され、起動速度が向上します。

  • 難読化(縮小とも呼ばれます): DEX ファイルのサイズを小さくするために、R8 はクラス、フィールド、メソッドの名前を短くします(たとえば、 com.example.MyActivitya.b.a になることがあります)。

Android Gradle プラグイン(AGP)バージョン 8.12.0 以降では、R8 は最適化フェーズの一環としてリソースも最適化します。詳細については、不要なリソースの削除の最適化 をご覧ください

最適化を有効にする

アプリの最適化を有効にするには、プロジェクトの AGP バージョンに基づいて適切な DSL を使用します。アプリの最適化は、公開前にテストするアプリの最終バージョン(通常はリリースビルド)でのみ有効にすることをおすすめします。最適化によりプロジェクトのビルド時間が長くなり、コードの変更方法によってはデバッグが難しくなる可能性があるためです。

AGP バージョン 9.3 以降の場合

AGP 9.3 以降でアプリの最適化を有効にするには:

  • リリースビルドのアプリレベルのビルドスクリプトの optimization ブロックで enable = true を設定します。
  • keep ルールを、 src/<variant>/keepRules ソースセットのサフィックス .keep のファイルに追加します。例: src/main/keepRules/custom-rules.keep

Kotlin

android {
    buildTypes {
        release {
            optimization {
                enable = true // Enables code and resource optimizations.
            }
        }
    }
}

Groovy

android {
    buildTypes {
        release {
            optimization {
                enable = true // Enables code and resource optimizations.
            }
        }
    }
}

AGP バージョン 9.3 より前のレガシー DSL

アプリの最適化を有効にするには、リリースビルドのアプリレベルのビルドスクリプトで isMinifyEnabled = true(コードの最適化の場合) と isShrinkResources = true(リソースの最適化の場合)を設定します。両方の設定を常に有効にすることをおすすめします。

レガシー DSL(Kotlin)

android {
    buildTypes {
        release {

            // Enables code optimizations.
            isMinifyEnabled = true

            // Enables resource shrinking.
            isShrinkResources = true

            proguardFiles(
                // Default file with automatically generated optimization rules.
                getDefaultProguardFile("proguard-android-optimize.txt"),

                ...
            )
            ...
        }
    }
    ...
}

レガシー DSL(Groovy)

android {
    buildTypes {
        release {

            // Enables code optimizations.
            minifyEnabled = true

            // Enables resource shrinking.
            shrinkResources = true

            // Default file with automatically generated optimization rules.
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt')

            ...
        }
    }
}

R8 の最適化を改善する

R8 のパフォーマンス上のメリットは、R8 が最適化できるコードベースの量に直接関係します。R8 を最大限に活用するには、次のベスト プラクティスに従ってください。

keep ルールを調整するには、R8 構成アナライザを使用します。

R8 構成アナライザを使用すると、次のことができます。

  • R8 構成アナライザ レポートで提供される指標をモニタリングして、R8 構成の全体的な品質を追跡し、改善します。
  • 最も広範な keep ルール(最適化を最も妨げるルール)を見つける
  • それらのルールがどのような最適化を妨げているかを把握して、調整する。

R8 構成アナライザは、AGP バージョン 9.3.0-alpha05 以降、または R8 バージョン 9.3.7-dev 以降で利用できます。詳細については、R8 構成を分析するをご覧ください。

不要なリソースの削除を最適化してアプリをさらに小さくする

AGP バージョン 8.12.0 では、不要なリソースの削除の最適化が導入されました。これは、リソースとコードの最適化を統合して、アプリをさらに小さく、高速にすることを目的としています。 不要なリソースの削除の最適化を行う前は、Android Asset Packaging Tool(AAPT2)が keep ルールを生成し、リソースの削除をコードとは別に行っていたため、相互に参照するアクセス不能なコードやリソースが保持されることがよくありました。

不要なリソースの削除の最適化では、リソースはプログラム コードの一部と見なされ、参照グラフを形成します。コードまたはリソースのコレクションが参照されていない場合、keep ルールで保護されないため、削除できます。

不要なリソースの削除の最適化を有効にする

AGP 8.12 または 8.13 の新しい不要なリソースの削除の最適化パイプラインを有効にするには、プロジェクトの gradle.properties ファイルに以下を追加します。

AGP 9.0.0 以降のバージョンを使用している場合は、android.r8.optimizedResourceShrinking=true を設定する必要はありません。ビルド構成で isShrinkResources = true が有効になっている場合、不要なリソースの削除の最適化が自動的に適用されます。

R8 の最適化設定を確認して構成する

R8 が 最適化機能を最大限に活用できるようにするには、プロジェクトの gradle.properties ファイルに 次の行が存在する場合は削除します。

bash android.enableR8.fullMode=false # Remove this line from your codebase.

アプリの最適化を有効にすると、特に R8 がクラス名またはメソッド名を変更した場合に、スタック トレースがわかりにくくなります。ソースコードに正しく対応するスタック トレースを取得するには、元のスタック トレースを復元するをご覧ください。

R8 が有効になっている場合は、起動パフォーマンスをさらに向上させるために、起動プロファイルも 作成する必要があります。

アプリの最適化を有効にするとエラーが発生する場合は、次の方法で修正できます。

ビルド速度の最適化に関心がある場合は、R8 の実行方法を構成するで、環境に基づいて R8 を構成する方法をご覧ください。

AGP と R8 のバージョンによる動作の変更

次の表に、Android Gradle プラグイン(AGP)と R8 コンパイラのさまざまなバージョンで導入された主な機能を示します。

AGP バージョン 導入された機能
9.3 簡素化された DSL:新しい `optimization {}` ブロックでは、構成が少なくて済みます。不要なリソースの削除の最適化は常に有効になり、デフォルトの Android keep ルールはオプトアウトされます。

`keepRules` ソースセット: 新しい DSL を使用する場合は、keep ルールを src/<variant>/keepRules ソースセットのサフィックスが .keep のファイルに配置する必要があります。ソースセットはレガシー DSL とも互換性があります。

KMP(Kotlin MultiPlatform)コンシューマ ルール: KMP では publish = true を設定する必要がなくなり、src/<variant>/keepRules ソースセットが .keep 拡張子でサポートされます。

レガシー DSL は引き続きサポートされています。
9.1 デフォルトでクラスが再パッケージ化される: R8 はクラスを再パッケージ化(最上位レベルの無名パッケージに移動)して DEX をさらに圧縮し、-repackageclasses オプションを指定する必要がなくなりました。この仕組みとオプトアウトの方法については、グローバル オプションをご覧ください。
9.0 不要なリソースの削除の最適化: デフォルトで有効になっています(android.r8.optimizedResourceShrinking を使用して制御します)。不要なリソースの削除の最適化により、リソースの削除をコード最適化パイプラインに統合できるため、アプリをより小さく、高速にすることができます。コードとリソースの両方の参照を同時に最適化することで、使用されていないコードからのみ参照されるリソースを特定して削除します。これは、以前の個別の最適化プロセスに比べて大幅な改善です。

これは、さまざまなフォーム ファクタのバーティカルで大量のリソースとコードを共有するアプリに特に便利で、アプリのサイズが 50% 以上削減されています。サイズが縮小されると、ダウンロードが小さくなり、インストールが高速になり、起動の高速化、レンダリングの改善、ANR の減少により、ユーザー エクスペリエンスが向上します。

ライブラリ ルールのフィルタリング: ライブラリ コンシューマ ルールでのグローバル オプション(-dontobfuscate など)のサポートが終了し、アプリでフィルタリングされるようになりました。詳細については、グローバル オプションを追加するをご覧ください。

Kotlin の null チェック: デフォルトで最適化されています(-processkotlinnullchecks を使用して制御します)。このバージョンでは、ビルド速度も大幅に改善されました。詳細については、追加の最適化のためのグローバル オプションをご覧ください。

特定のパッケージを最適化する: packageScope を使用して、特定のパッケージを最適化できます。これは試験運用版のサポートです。詳細については、を使用して指定したパッケージを最適化するpackageScopeをご覧ください。

デフォルトで最適化: -dontoptimize が含まれているため、getDefaultProguardFile("proguard-android.txt") のサポートが終了しました。代わりに、"proguard-android-optimize.txt" を使用してください。アプリで最適化をグローバルに無効にする必要がある場合は、proguard ファイルにフラグを手動で追加します
8.12 不要なリソースの削除の最適化: 初期サポートが追加されました(android.r8.optimizedResourceShrinking を使用して制御します)。 不要なリソースの削除の最適 4により、リソースの削除をコード最適化パイプラインに統合できます。このバージョンの AGP では、手動で有効にする必要があります。

[Logcat の再トレース]: Android Studio の [Logcat] ウィンドウでの自動再トレースのサポート。
8.6 再トレースの改善: すべての minSdk レベルで、ファイル名と行番号の再トレースがデフォルトで含まれるようになりました(以前はバージョン 8.2 で minSdk 26 以上が必要でした)。

R8 を更新すると、難読化されたビルドのスタック トレースを簡単かつ明確に読み取ることができます。このバージョンでは、行番号とソースファイルのマッピング方法が改善され、Android Studio の Logcat などのツールでクラッシュを元のソースコードに自動的に再トレースしやすくなりました。
8.0 デフォルトでフルモード: R8 フルモード では、最適化が大幅に強化されます。デフォルトでは有効になっています。android.enableR8.fullMode=false を使用してオプトアウトできます。
7.0 フルモードが利用可能: android.enableR8.fullMode=true を使用してオプトイン機能として導入されました。フルモードでは、コードがリフレクションやその他の動的機能を使用する方法についてより厳密な想定を行うことで、より強力な最適化が適用されます。アプリのサイズが縮小され、パフォーマンスが向上しますが、必要なコードが削除されないように、追加の keep ルールが必要になる場合があります。