Utilizzare R8 Configuration Analyzer

R8 Configuration Analyzer è uno strumento progettato per aiutarti a massimizzare i vantaggi in termini di prestazioni di R8 fornendo informazioni dettagliate sulla qualità della configurazione della tua app. Ti consente di monitorare e migliorare l'ottimizzazione di R8 monitorando le metriche chiave, in particolare i punteggi di riduzione, ottimizzazione e offuscamento, che indicano la percentuale di codebase disponibile per l'ottimizzazione. Identificando regole di conservazione ampie o non necessarie, incluse quelle introdotte da librerie di terze parti, l'analizzatore ti aiuta a perfezionare la configurazione per garantire che R8 possa ottimizzare efficacemente il maggior numero possibile di classi, campi e metodi.

Generare il report

A partire da AGP 9.3.0-alpha05 e versioni successive, il report viene generato automaticamente in build/outputs/mapping/release/configanalyzer.html quando esegui una build R8. Per disattivare la generazione automatica degli output, imposta la seguente proprietà Gradle:

android.experimental.r8.enableR8ConfigurationAnalyzer=false

Per AGP 9.2 e versioni precedenti, imposta la com.android.tools.r8.dumpkeepradiushtmltodirectory proprietà di sistema quando esegui un'attività Gradle con una build abilitata con R8.

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

Ad esempio, utilizza il seguente comando per generare il report HTML nella directory /tmp/r8analysis:

// 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

Comprendere il report

R8 Configuration Analyzer fornisce informazioni sulla configurazione di R8 della tua app e sull'impatto di ogni regola di conservazione sull'app. In questo modo, puoi ottenere la massima ottimizzazione da R8, migliorando le prestazioni dell'app. Utilizza i seguenti punteggi per capire quanta parte della codebase è disponibile per l'ottimizzazione da parte di R8.

Esempio della sezione di riepilogo del report
Figura 1. Un esempio della sezione di riepilogo del report.

Punteggio di riduzione

Quando R8 riduce le dimensioni dell'app, ne riduce le dimensioni complessive identificando ed eliminando il codice e le risorse inutilizzate, assicurandosi che la build finale sia il più snella possibile. Il punteggio di riduzione tiene traccia della percentuale di classi, campi e metodi soggetti a riduzione. Ad esempio, un punteggio di riduzione del 66% significa che R8 può eseguire la riduzione nel 66% della codebase.

Punteggio di ottimizzazione

R8 esegue ottimizzazioni come l'inlining dei metodi e l'unione delle classi, che comportano miglioramenti in termini di avvio e memoria per l'app. Il punteggio di ottimizzazione tiene traccia della percentuale di classi, campi e metodi soggetti alle ottimizzazioni di R8. Ad esempio, se il punteggio di ottimizzazione è del 66%, significa che R8 può eseguire l'ottimizzazione solo nel 66% della codebase.

Punteggio di offuscamento

Offuscando classi, campi e metodi con nomi più brevi, R8 riduce la traccia dei metadati dell'app per risparmiare memoria. Il punteggio di offuscamento misura la percentuale di codice disponibile per l'offuscamento all'interno della codebase.

Perfezionare le regole di conservazione

Per migliorare i punteggi e sbloccare una migliore ottimizzazione di R8, devi perfezionare le regole di conservazione in modo che non impediscano inutilmente a R8 di ottimizzare l'app. Devi conservare solo le classi, i metodi o i campi a cui si accede utilizzando la reflection.

Per farlo, utilizza l'analisi delle regole di conservazione.

Esempio di analisi della regola di conservazione
Figura 2. Un esempio di analisi delle regole di conservazione.

Per visualizzare l'analisi dettagliata di una regola, fai clic su di essa per aprire la schermata dei dettagli.

Esempio di analisi della regola di conservazione
Figura 3. Un esempio di analisi delle regole di conservazione.

Come perfezionare le regole di conservazione

Per perfezionare le regole di conservazione e sbloccare il pieno potenziale delle ottimizzazioni di R8 per la tua app:

  1. Per ogni regola di conservazione, consulta la percentuale di classi, campi e metodi che non possono essere ottimizzati da R8 in Configuration Analyzer. Utilizza queste informazioni per identificare le regole di conservazione che impediscono l'ottimizzazione in un numero elevato di classi, campi o metodi. Vengono elencate anche le proprietà di ottimizzazione impedite da ogni regola di conservazione.
  2. Se vedi una regola di conservazione che impedisce l'ottimizzazione di un numero elevato di classi, devi assicurarti di controllare quali classi, campi e metodi non possono essere ottimizzati dalla regola di conservazione per verificare se questa regola conserva elementi che non vengono richiamati dinamicamente utilizzando la reflection.
  3. Riduci l'ottimizzazione bloccata dalle regole di conservazione scegliendo la giusta opzione di conservazione e seguendo le best practice per indirizzare solo le classi, i campi o i metodi necessari.
  4. Esamina ed esegui test che coprano le classi, i campi e i metodi interessati della regola di conservazione e perfeziona le regole di conservazione.

Esaminare l'ottimizzazione delle librerie

Quando integri librerie di terze parti, spesso includono le proprie regole di conservazione dei consumatori per funzionare con R8. Poiché l'autore della libreria non può prevedere la tua implementazione specifica, a volte scrive regole conservative e di ampia portata che impediscono l'ottimizzazione in un numero maggiore di classi, campi e metodi rispetto al necessario. Ciò potrebbe impedire a R8 di ottimizzare parti dell'app che non hanno nulla a che fare con l'esecuzione effettiva della libreria in fase di runtime. Puoi utilizzare R8 Configuration Analyzer per identificare le librerie che introducono regole che influiscono negativamente sull'ottimizzazione della tua app.

Utilizza l'analizzatore di configurazione per esaminare l'effetto combinato di tutte le regole di conservazione dei consumatori unite. Analizzando l'impatto di ogni regola di conservazione proveniente da una libreria di terze parti, puoi identificare e tracciare le librerie di terze parti specifiche che impediscono un'elevata quantità di ottimizzazione nella tua app.

Come ottimizzare le librerie

  • Se una libreria include una regola eccessivamente ampia, ti consigliamo di contattare il gestore della libreria con i dati del report per dimostrare in che modo le regole attuali influiscono sui punteggi di ottimizzazione della tua app. Se si tratta di una libreria esterna, cerca i bug esistenti nella libreria prima di segnalare i problemi.
  • Se necessario, puoi testare i potenziali miglioramenti filtrando le regole di una libreria specifica. Puoi importare le regole della libreria nel tuo progetto, escludere quelle ampie ed eseguire di nuovo l'analizzatore di configurazione per misurare i potenziali guadagni in termini di dimensioni e prestazioni.

Regole sussunte

Potrebbero verificarsi casi in cui più regole di conservazione si sovrappongono e una delle regole potrebbe impedire un'ottimizzazione maggiore del necessario. Se nella codebase sono presenti due regole di conservazione.

# 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

La prima regola di conservazione, che impedisce l'ottimizzazione dell'intero pacchetto, sussume la seconda regola di conservazione, che ha come target una classe all'interno del pacchetto conservato dalla prima regola di conservazione. Quando le regole di conservazione si sovrappongono, una potrebbe bloccare più ottimizzazioni del necessario. Perfezionando queste regole sovrapposte, puoi massimizzare l'ottimizzazione di R8 ed eliminare il debito tecnico. Questa procedura prevede la semplificazione della configurazione per garantire che venga conservato solo il codice essenziale, sbloccando al contempo il pieno potenziale delle funzionalità di ottimizzazione di R8.

Esempio della sezione di riepilogo del report
Figura 4. Un esempio di regole sussunte nel report.

Ottimizzare le regole sussunte

  1. Trova le regole di conservazione sussunte utilizzando R8 Configuration Analyzer.
  2. Identifica le classi, i campi o i metodi esatti nella codebase che si basano effettivamente sulla reflection e che devono essere conservati utilizzando le regole di conservazione. In questo modo, puoi perfezionare le regole di conservazione.
  3. Utilizzando l'analizzatore di configurazione, confronta l'impatto di ogni regola che ha come target le stesse classi, gli stessi campi o gli stessi metodi. Puoi utilizzare la percentuale di ottimizzazione impedita da ogni regola di conservazione per identificare quale è più ampia e quale è una regola di conservazione ristretta.
    1. Se la regola ristretta è scritta con precisione, conservando solo i membri o le classi esatti a cui si accede in modo riflessivo, rimuovi la regola di conservazione più ampia. In questo modo, puoi sbloccare in sicurezza le ottimizzazioni di R8 per il resto del pacchetto.
    2. Se la regola ampia ha come target le classi corrette, mantienila ed elimina la regola ristretta. La regola ristretta è solo un ingombro ridondante. Assicurati di perfezionare la regola ampia in modo che abbia come target solo le classi, i campi o i metodi che hai identificato.

Verifica e testa le modifiche: esegui di nuovo l'analizzatore di configurazione per assicurarti che il conflitto sia stato risolto. Dopodiché, compila una build di release e testa le modifiche per assicurarti che la codebase funzioni come previsto.

Rimuovere le regole non necessarie

Utilizzando l'analizzatore di configurazione, puoi controllare sistematicamente la codebase per identificare ed eliminare le regole di conservazione obsolete che ingombrano la configurazione. R8 Configuration Analyzer evidenzia in particolare due fonti principali di regole non necessarie:

  • Regole inutilizzate: regole che corrispondono a zero classi, metodi o campi nella build corrente. Spesso persistono dopo il refactoring del codice, la rimozione delle dipendenze o le configurazioni di copia e incolla che non sono più pertinenti, aggiungendo una complessità di configurazione non necessaria.
  • Regole identiche: le regole di conservazione identiche sono regole che hanno come target le stesse classi, gli stessi campi e gli stessi metodi o dichiarazioni duplicate di regole di conservazione nello stesso file di regole di conservazione o in file diversi.

Entrambi i tipi di regole ingombrano la configurazione, rendendola più difficile da gestire ed eseguire il debug. Identificandole, puoi liberare spazio nella configurazione.