1. Introduzione
Ultimo aggiornamento: 11/03/2021
Perché dobbiamo misurare il rendimento delle visualizzazioni?
Le visualizzazioni sono una parte fondamentale delle applicazioni per Android che influisce direttamente sull'esperienza utente. Ad esempio, l'attività o il fragment contiene l'interfaccia utente che contiene i componenti View con cui gli utenti interagiscono. Gli utenti non sono in grado di vedere l'intero contenuto della UI finché non viene visualizzato completamente sullo schermo. Le schermate lente e bloccate compromettono direttamente l'interazione degli utenti con la tua app e creano un'esperienza utente negativa.
Firebase Performance Monitoring non fornisce queste metriche relative alle prestazioni pronte all'uso?
Firebase Performance Monitoring acquisisce automaticamente alcuni dati sulle prestazioni, ad esempio il tempo di avvio dell'app (ovvero il tempo di caricamento della prima attività) e le prestazioni di rendering dello schermo (ovvero frame lenti e bloccati per le attività, ma non per i frammenti). Tuttavia, le app di settore di solito non hanno molte attività, ma piuttosto un'attività e più frammenti. Inoltre, molte app di solito implementano le proprie visualizzazioni personalizzate per casi d'uso più complessi. Pertanto, spesso è utile capire come misurare il tempo di caricamento e le prestazioni di rendering dello schermo di attività e frammenti strumentando le tracce di codice personalizzato nella tua app. Puoi estendere facilmente questo codelab per misurare le prestazioni dei componenti di visualizzazione personalizzata.
Cosa imparerai a fare
- Come aggiungere Firebase Performance Monitoring a un'app per Android
- Comprendere il caricamento di un'attività o di un fragment
- Come instrumentare le tracce di codice personalizzato per misurare il tempo di caricamento di un'attività o di un fragment
- Informazioni sul rendering dello schermo e su cosa sono un frame lento/bloccato
- Come instrumentare le tracce di codice personalizzato con le metriche per registrare le schermate lente/bloccate
- Come visualizzare le metriche raccolte nella console Firebase
Che cosa ti serve
- Android Studio 4.0 o versioni successive
- Un dispositivo/emulatore Android
- Java versione 8 o successive
2. Configurazione
Ottieni il codice
Esegui i seguenti comandi per clonare il codice di esempio per questo codelab. Verrà creata una cartella denominata codelab-measure-android-view-performance
sul tuo computer:
$ git clone https://github.com/FirebaseExtended/codelab-measure-android-view-performance.git
$ cd codelab-measure-android-view-performance
Se non hai git sul tuo computer, puoi anche scaricare il codice direttamente da GitHub.
Importa il progetto measure-view-performance-start
in Android Studio. Probabilmente vedrai alcuni errori di compilazione o un avviso relativo a un file google-services.json
mancante. Correggeremo questo problema nella sezione successiva di questo passaggio.
In questo codelab, utilizzeremo il plug-in Firebase Assistant per registrare la nostra app per Android con un progetto Firebase e aggiungere i file di configurazione, i plug-in e le dipendenze Firebase necessari al nostro progetto Android, tutto da Android Studio.
Connetti la tua app a Firebase
- Vai ad Android Studio/Guida > Controlla aggiornamenti per assicurarti di utilizzare le versioni più recenti di Android Studio e dell'assistente Firebase.
- Seleziona Strumenti > Firebase per aprire il riquadro Assistente.
- Scegli Performance Monitoring da aggiungere alla tua app, poi fai clic su Inizia a utilizzare Performance Monitoring.
- Fai clic sul pulsante per creare un nuovo progetto, quindi inserisci un nome (ad esempio,
Measure Performance Codelab
). - Fai clic su Continua.
- Se richiesto, leggi e accetta i termini di Firebase, quindi fai clic su Continua.
- (Facoltativo) Attiva l'assistenza AI nella console Firebase (denominata "Gemini in Firebase").
- Per questo codelab non hai bisogno di Google Analytics, quindi disattiva l'opzione Google Analytics.
- Dovresti visualizzare una finestra di dialogo per collegare la nuova app Firebase al progetto Android Studio.
- In Android Studio, nel riquadro Assistente, dovresti vedere la conferma che la tua app è connessa a Firebase.
Aggiungere Performance Monitoring alla tua app
Nel riquadro Assistente di Android Studio, fai clic su Aggiungi Performance Monitoring alla tua app.
Dovresti visualizzare una finestra di dialogo per Accettare modifiche, dopodiché Android Studio dovrebbe sincronizzare la tua app per assicurarsi che siano state aggiunte tutte le dipendenze necessarie.
Infine, nel riquadro Assistente di Android Studio dovresti visualizzare il messaggio di conferma che tutte le dipendenze sono configurate correttamente.
Come passaggio aggiuntivo, attiva la registrazione di debug seguendo le istruzioni riportate nel passaggio "(Facoltativo) Attiva la registrazione di debug". Le stesse istruzioni sono disponibili anche nella documentazione pubblica.
3. Esegui l'app
Se hai integrato correttamente la tua app con l'SDK Performance Monitoring, ora il progetto dovrebbe essere compilato. In Android Studio, fai clic su Esegui > Esegui "app" per creare ed eseguire l'app sul dispositivo/emulatore Android connesso.
L'app ha due pulsanti che ti portano a un'attività e a un frammento corrispondenti, come questo:
Nei passaggi successivi di questo codelab, imparerai a misurare il tempo di caricamento e il rendimento del rendering dello schermo della tua attività o del tuo fragmento.
4. Comprendere il caricamento di un'attività o di un fragment
In questo passaggio, scopriremo cosa fa il sistema durante il caricamento di un'attività o di un frammento.
Informazioni sul caricamento di un'attività
Per un'attività, il tempo di caricamento è definito come il tempo che intercorre tra la creazione dell'oggetto Activity e il momento in cui il primo frame viene disegnato completamente sullo schermo (questo è il momento in cui l'utente vedrà per la prima volta l'intera UI dell'attività). Per misurare se la tua app è completamente disegnata, puoi utilizzare il metodo reportFullyDrawn()
per misurare il tempo trascorso tra l'avvio dell'applicazione e la visualizzazione completa di tutte le risorse e delle gerarchie di visualizzazione.
In linea generale, quando l'app chiama startActivity(Intent)
, il sistema esegue automaticamente i seguenti processi. Ogni processo richiede tempo per essere completato, il che aumenta la durata del periodo di tempo che intercorre tra la creazione dell'attività e il momento in cui l'utente vede la relativa UI sullo schermo.
Comprendere il caricamento di un frammento
Analogamente all'attività, il tempo di caricamento di un fragment è definito come il tempo che intercorre tra l'attacco del fragment alla sua attività host e il momento in cui il primo frame della visualizzazione del fragment viene disegnato completamente sullo schermo.
5. Misurare il tempo di caricamento di un'attività
I ritardi nel primo frame possono portare a un'esperienza utente negativa, quindi è importante capire il ritardo di caricamento iniziale che riscontrano gli utenti. Puoi instrumentare una traccia di codice personalizzato per misurare questo tempo di caricamento:
- Avvia la traccia del codice personalizzato (denominata
TestActivity-LoadTime
) nella classe Activity non appena viene creato l'oggetto Activity.
TestActivity.java
public class TestActivity extends AppCompatActivity {
// TODO (1): Start trace recording as soon as the Activity object is created.
private final Trace viewLoadTrace = FirebasePerformance.startTrace("TestActivity-LoadTime");
// ...
}
- Esegui l'override del callback
onCreate()
e recupera la visualizzazione aggiunta dal metodosetContentView()
.
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Current Activity's main View (as defined in the layout xml file) is inflated after this
setContentView(R.layout.activity_test);
// ...
// TODO (2): Get the View added by Activity's setContentView() method.
View mainView = findViewById(android.R.id.content);
// ...
}
- Abbiamo incluso un'implementazione di
FistDrawListener
, che ha due callback:onDrawingStart()
eonDrawingFinish()
(per maggiori dettagli suFirstDrawListener
e su cosa può influire sul suo rendimento, consulta la sezione successiva). RegistraFirstDrawListener
alla fine delonCreate()
callback di Activity. Devi interrompere laviewLoadTrace
nelonDrawingFinish()
callback.
TestActivity.java
// TODO (3): Register the callback to listen for first frame rendering (see
// "OnFirstDrawCallback" in FirstDrawListener) and stop the trace when View drawing is
// finished.
FirstDrawListener.registerFirstDrawListener(mainView, new FirstDrawListener.OnFirstDrawCallback() {
@Override
public void onDrawingStart() {
// In practice you can also record this event separately
}
@Override
public void onDrawingFinish() {
// This is when the Activity UI is completely drawn on the screen
viewLoadTrace.stop();
}
});
- Esegui di nuovo l'app. Poi, filtra logcat con "Logging trace metric". Tocca il pulsante
LOAD ACTIVITY
e cerca log come quelli riportati di seguito:
I/FirebasePerformance: Logging trace metric: TestActivity-LoadTime (duration: XXXms)
🎉 Congratulazioni! Hai misurato correttamente il tempo di caricamento di un'attività e hai inviato i dati a Firebase Performance Monitoring. Visualizzeremo la metrica registrata nella console Firebase più avanti in questo codelab.
Scopo di FirstDrawListener
Nella sezione precedente, abbiamo registrato un FirstDrawListener
. Lo scopo di FirstDrawListener
è misurare quando il primo frame ha iniziato e terminato il disegno.
Implementa ViewTreeObserver.OnDrawListener
e sostituisce il callback onDraw()
richiamato quando l'albero della visualizzazione sta per essere disegnato. Quindi esegue il wrapping del risultato per fornire due callback di utilità onDrawingStart()
e onDrawingFinish()
.
Il codice completo per FirstDrawListener
è disponibile nel codice sorgente di questo codelab.
6. Misurare il tempo di caricamento di un fragmento
La misurazione del tempo di caricamento di un fragment è simile a quella di un'attività, ma con alcune piccole differenze. Anche in questo caso, strumenteremo una traccia di codice personalizzato:
- Ignora il callback
onAttach()
e inizia a registrare il tuofragmentLoadTrace
. Chiameremo questa tracciaTest-Fragment-LoadTime
.
Come spiegato in un passaggio precedente, l'oggetto Fragment può essere creato in qualsiasi momento, ma diventa attivo solo quando è collegato alla sua attività host.
TestFragment.java
public class TestFragment extends Fragment {
// TODO (1): Declare the Trace variable.
private Trace fragmentLoadTrace;
@Override
public void onAttach(@NonNull Context context) {
super.onAttach(context);
// TODO (2): Start trace recording as soon as the Fragment is attached to its host Activity.
fragmentLoadTrace = FirebasePerformance.startTrace("TestFragment-LoadTime");
}
- Registra
FirstDrawListener
nel callbackonViewCreated()
. Poi, in modo simile all'esempio di Attività, interrompi la traccia inonDrawingFinish()
.
TestFragment.java
@Override
public void onViewCreated(@NonNull View mainView, Bundle savedInstanceState) {
super.onViewCreated(mainView, savedInstanceState);
// ...
// TODO (3): Register the callback to listen for first frame rendering (see
// "OnFirstDrawCallback" in FirstDrawListener) and stop the trace when view drawing is
// finished.
FirstDrawListener.registerFirstDrawListener(mainView, new FirstDrawListener.OnFirstDrawCallback() {
@Override
public void onDrawingStart() {
// In practice you can also record this event separately
}
@Override
public void onDrawingFinish() {
// This is when the Fragment UI is completely drawn on the screen
fragmentLoadTrace.stop();
}
});
- Esegui di nuovo l'app. Poi, filtra logcat con "Logging trace metric". Tocca il pulsante
LOAD FRAGMENT
e cerca log come quelli riportati di seguito:
I/FirebasePerformance: Logging trace metric: TestFragment-LoadTime (duration: XXXms)
🎉 Congratulazioni! Hai misurato correttamente il tempo di caricamento di un fragment e hai inviato i dati a Firebase Performance Monitoring. Visualizzeremo la metrica registrata nella console Firebase più avanti in questo codelab.
7. Informazioni sul rendering dello schermo e su cosa sono un frame lento/bloccato
Il rendering dell'interfaccia utente è l'azione di generare un frame dalla tua app e visualizzarlo sullo schermo. Per garantire un'interazione fluida dell'utente con la tua app, quest'ultima deve eseguire il rendering dei frame in meno di 16 ms per raggiungere i 60 frame al secondo ( perché 60 fps?). Se il rendering dell'interfaccia utente della tua app è lento, il sistema è costretto a saltare i frame e l'utente percepirà dei rallentamenti nell'app. Questo fenomeno è chiamato jank.
Allo stesso modo, i frame bloccati sono frame dell'interfaccia utente che richiedono più di 700 ms per il rendering. Questo ritardo è un problema perché la tua app sembra bloccata e non risponde all'input dell'utente per quasi un secondo intero durante il rendering del frame.
8. Misurare i frame lenti/bloccati di un fragment
Firebase Performance Monitoring acquisisce automaticamente i frame lenti/congelati per un'attività (ma solo se è accelerata dall'hardware). Tuttavia, questa funzionalità non è attualmente disponibile per i frammenti. I frame lenti/congelati di un frammento sono definiti come i frame lenti/congelati per l'intera attività tra i callback onFragmentAttached()
e onFragmentDetached()
nel ciclo di vita del frammento.
Prendendo spunto dalla classe AppStateMonitor
(che fa parte dell'SDK Performance Monitoring responsabile della registrazione delle tracce dello schermo per Activity), abbiamo implementato la classe ScreenTrace
(che fa parte di questo repository del codice sorgente del codelab). La classe ScreenTrace
può essere collegata al callback del ciclo di vita dell'FragmentManager
per acquisire i frame lenti/congelati. Questa classe fornisce due API pubbliche:
recordScreenTrace()
: avvia la registrazione di una traccia dello schermosendScreenTrace()
: interrompe la registrazione di una traccia dello schermo e allega metriche personalizzate per registrare i conteggi di frame totali, lenti e bloccati
Se colleghi queste metriche personalizzate, le tracce dello schermo per i fragment possono essere gestite allo stesso modo delle tracce dello schermo per un'attività e possono essere visualizzate insieme ad altre tracce di rendering dello schermo nella dashboard Rendimento della console Firebase.
Ecco come registrare le tracce dello schermo per il tuo frammento:
- Inizializza la classe
ScreenTrace
nell'attività che ospita il frammento.
MainActivity.java
// Declare the Fragment tag
private static final String FRAGMENT_TAG = TestFragment.class.getSimpleName();
// TODO (1): Declare the ScreenTrace variable.
private ScreenTrace screenTrace;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// TODO (2): Initialize the ScreenTrace variable.
screenTrace = new ScreenTrace(this, FRAGMENT_TAG);
// ...
}
- Quando carichi il frammento, registrati per
FragmentLifecycleCallbacks
ed esegui l'override dei callbackonFragmentAttached()
eonFragmentDetached()
. Lo abbiamo fatto per te. Devi avviare la registrazione delle tracce dello schermo nel callbackonFragmentAttached()
e interromperla nel callbackonFragmentDetached()
.
MainActivity.java
private final FragmentManager.FragmentLifecycleCallbacks fragmentLifecycleCallbacks =
new FragmentManager.FragmentLifecycleCallbacks() {
@Override
public void onFragmentAttached(@NonNull FragmentManager fm, @NonNull Fragment f, @NonNull Context context) {
super.onFragmentAttached(fm, f, context);
// TODO (3): Start recording the screen traces as soon as the Fragment is
// attached to its host Activity.
if (FRAGMENT_TAG.equals(f.getTag()) && screenTrace.isScreenTraceSupported()) {
screenTrace.recordScreenTrace();
}
}
@Override
public void onFragmentDetached(@NonNull FragmentManager fm, @NonNull Fragment f) {
super.onFragmentDetached(fm, f);
// TODO (4): Stop recording the screen traces as soon as the Fragment is
// detached from its host Activity.
if (FRAGMENT_TAG.equals(f.getTag()) && screenTrace.isScreenTraceSupported()) {
screenTrace.sendScreenTrace();
}
// Unregister Fragment lifecycle callbacks after the Fragment is detached
fm.unregisterFragmentLifecycleCallbacks(fragmentLifecycleCallbacks);
}
};
- Esegui di nuovo l'app, poi tocca il pulsante
LOAD FRAGMENT
. Attendi qualche secondo, poi fai clic suback button
nella barra di navigazione in basso.
Filtra logcat con "Metrica di traccia di logging", quindi cerca log come quelli riportati di seguito:
I/FirebasePerformance: Logging trace metric: _st_MainActivity-TestFragment (duration: XXXms)
Filtra logcat con "FireperfViews", quindi cerca log come quelli riportati di seguito:
D/FireperfViews: sendScreenTrace MainActivity-TestFragment, name: _st_MainActivity-TestFragment, total_frames: XX, slow_frames: XX, frozen_frames: XX
🎉 Congratulazioni! Hai misurato correttamente i frame lenti/bloccati per un fragment e hai inviato i dati a Firebase Performance Monitoring. Visualizzeremo le metriche registrate nella console Firebase più avanti in questo codelab.
9. Controllare le metriche nella console Firebase
- Nel logcat, fai clic sull'URL della console Firebase per visitare la pagina dei dettagli di una traccia.
In alternativa, nella console Firebase, seleziona il progetto che contiene la tua app. Nel pannello a sinistra, individua la sezione Release e monitoraggio, quindi fai clic su Rendimento.
- Nella scheda principale Dashboard, scorri verso il basso fino alla tabella delle tracce, quindi fai clic sulla scheda Tracce personalizzate. In questa tabella vedrai le tracce di codice personalizzato che abbiamo aggiunto in precedenza, oltre ad alcune tracce predefinite, come la traccia
_app_start
. - Trova le due tracce di codice personalizzato,
TestActivity-LoadTime
eTestFragment-LoadTime
. Fai clic su Durata per visualizzare ulteriori dettagli sui dati raccolti.
- La pagina dei dettagli della traccia del codice personalizzato mostra informazioni sulla durata della traccia (ovvero il tempo di caricamento misurato).
- Puoi anche visualizzare i dati sul rendimento della traccia dello schermo personalizzata.
- Torna alla scheda principale Dashboard, scorri verso il basso fino alla tabella delle tracce e poi fai clic sulla scheda Rendering dello schermo. In questa tabella vedrai le tracce delle schermate personalizzate che abbiamo aggiunto in precedenza, oltre a eventuali tracce delle schermate predefinite, come la traccia
MainActivity
. - Trova la tua traccia personalizzata dello schermo,
MainActivity-TestFragment
. Fai clic sul nome della traccia per visualizzare i dati aggregati di rendering lento e frame bloccati.
10. Complimenti
Complimenti! Hai misurato correttamente il tempo di caricamento e le prestazioni di rendering dello schermo di un'attività e di un frammento utilizzando Firebase Performance Monitoring.
Cosa hai realizzato
- Hai integrato Firebase Performance Monitoring in un'app di esempio
- Ora comprendi il ciclo di vita del caricamento delle visualizzazioni
- Hai misurato il tempo di caricamento di un'attività e di un frammento aggiungendo tracce di codice personalizzato.
- Hai registrato frame lenti/congelati aggiungendo tracce dello schermo personalizzate con metriche personalizzate.
Passaggi successivi
Firebase Performance offre più modi per misurare le prestazioni della tua app oltre alla traccia personalizzata. Misura automaticamente i dati sulle prestazioni di avvio dell'app, dell'app in primo piano e dell'app in background. È il momento di controllare queste metriche nella console Firebase.
Inoltre, Firebase Performance offre il monitoraggio automatico delle richieste di rete HTTP/S. In questo modo, puoi instrumentare facilmente le richieste di rete senza scrivere una sola riga di codice. Puoi provare a inviare alcune richieste di rete dalla tua app e trovare le metriche nella console Firebase?
Bonus
Ora che sai come misurare il tempo di caricamento e il rendimento del rendering dello schermo della tua attività/frammento utilizzando le tracce di codice personalizzato, puoi esplorare la nostra base di codice open source per vedere se riesci ad acquisire queste metriche pronte all'uso per qualsiasi attività/frammento che fa parte dell'app? Se vuoi, puoi inviare la PR. :-)
11. Apprendimento bonus
Comprendere cosa succede durante il caricamento di un'attività ti aiuterà a capire meglio le caratteristiche di rendimento della tua app. In un passaggio precedente, abbiamo descritto a livello generale cosa succede durante il caricamento di un'attività, ma il seguente diagramma descrive ogni fase in modo molto più dettagliato.