Durante l'avvio dell'app, la tua app fa la prima impressione sugli utenti. L'avvio dell'app deve essere rapido per caricare e visualizzare le informazioni necessarie all'utente per utilizzare l'app. Se l'avvio dell'app richiede troppo tempo, gli utenti potrebbero uscire dall'app perché l'attesa è troppo lunga.
Ti consigliamo di utilizzare la libreria Macrobenchmark per misurare l'avvio. La libreria fornisce una panoramica e tracce di sistema dettagliate per vedere esattamente cosa succede durante l'avvio.
Le tracce di sistema forniscono informazioni utili su ciò che accade sul tuo dispositivo, il che ti aiuta a capire cosa fa la tua app durante l'avvio e a identificare potenziali aree di ottimizzazione.
Per analizzare l'avvio dell'app:
- Configura un ambiente per registrare le tracce per l'avvio dell'app.
- Comprendere le tracce di sistema.
- Esamina un report di traccia utilizzando Android Studio Profilers o Perfetto.
Passaggi per analizzare e ottimizzare l'avvio
Le app spesso devono caricare risorse specifiche durante l'avvio, che sono fondamentali per gli utenti finali. Le risorse non essenziali possono attendere il caricamento fino al completamento dell'avvio.
Per fare compromessi in termini di prestazioni, tieni presente quanto segue:
Utilizza la libreria Macrobenchmark per misurare il tempo impiegato da ogni operazione e identificare i blocchi che richiedono molto tempo per essere completati.
Conferma che l'operazione che richiede molte risorse è fondamentale per l'avvio dell'app. Se l'operazione può attendere fino al rendering completo dell'app, può contribuire a ridurre al minimo i vincoli delle risorse all'avvio.
Assicurati che questa operazione venga eseguita all'avvio dell'app. Spesso, operazioni non necessarie possono essere chiamate da codice legacy o librerie di terze parti.
Sposta le operazioni a lunga esecuzione in background, se possibile. I processi in background possono comunque influire sull'utilizzo della CPU durante l'avvio.
Dopo aver esaminato a fondo l'operazione, puoi decidere il compromesso tra il tempo necessario per il caricamento e la necessità di includerla all'avvio dell'app. Quando modifichi il flusso di lavoro della tua app, ricorda di includere la possibilità di regressione o modifiche che causano interruzioni.
Ottimizza e misura di nuovo finché non sei soddisfatto del tempo di avvio della tua app. Per ulteriori informazioni, consulta Utilizzare le metriche per rilevare e diagnosticare i problemi.
Misurare e analizzare il tempo trascorso nelle operazioni principali
Quando hai una traccia completa dell'avvio dell'app, esaminala e misura il tempo
impiegato per le operazioni principali come bindApplication o activityStart. Ti
consigliamo di utilizzare Perfetto o gli Android
Studio Profilers per analizzare queste tracce.
Esamina il tempo totale trascorso durante l'avvio dell'app per identificare eventuali operazioni che:
- Occupano intervalli di tempo ampi e possono essere ottimizzati. Ogni millisecondo conta in termini di
rendimento. Ad esempio, cerca i tempi di disegno
Choreographer, i tempi di composizione iniziali, i tempi di caricamento della libreria, le transazioniBindero i tempi di caricamento delle risorse. Per un avvio generale, esamina tutte le operazioni che richiedono più di 20 ms. - Blocca il thread principale. Per maggiori informazioni, vedi Navigare in un report Systrace.
- Non è necessario eseguirli durante l'avvio.
- Può attendere fino al disegno del primo fotogramma.
Esamina ulteriormente ciascuna di queste tracce per trovare lacune nelle prestazioni.
Identificare le operazioni costose sul thread principale
La best practice prevede di tenere le operazioni costose come I/O di file e accesso alla rete
fuori dal thread principale. Ciò è altrettanto importante durante l'avvio dell'app,
perché le operazioni costose sul thread principale possono rendere l'app non reattiva
e ritardare altre operazioni critiche.
StrictMode.ThreadPolicy può
aiutare a identificare i casi in cui si verificano operazioni costose sul thread principale.
È buona norma attivare StrictMode nelle build di debug per identificare i problemi il prima possibile, come mostrato nell'esempio seguente:
class MyApplication : Application() {
override fun onCreate() {
super.onCreate()
...
if (BuildConfig.DEBUG)
StrictMode.setThreadPolicy(
StrictMode.ThreadPolicy.Builder()
.detectAll()
.penaltyDeath()
.build()
)
...
}
}
L'utilizzo di StrictMode.ThreadPolicy attiva le norme sui thread in tutte le build di debug
e l'app va in arresto anomalo ogni volta che vengono rilevate violazioni delle norme sui thread, il che
rende difficile non notare le violazioni delle norme sui thread.
TTID e TTFD
Per visualizzare il tempo necessario all'app per produrre il primo frame, misura il tempo alla visualizzazione iniziale (TTID). Tuttavia, questa metrica non riflette necessariamente il tempo che intercorre prima che l'utente possa iniziare a interagire con la tua app. La metrica tempo al caricamento completo (TTFD) è più utile per misurare e ottimizzare i percorsi del codice necessari per avere uno stato dell'app completamente utilizzabile.
Per strategie sulla segnalazione del momento in cui l'interfaccia utente dell'app è completamente disegnata, consulta Migliorare l'accuratezza della tempistica di avvio.
Ottimizza sia per il TTID che per il TTFD, perché entrambi sono importanti nelle rispettive aree. Un TTID breve aiuta l'utente a capire che l'app si sta effettivamente avviando. Mantenere breve il TTFD è importante per garantire che l'utente possa iniziare a interagire rapidamente con l'app.
Analizzare lo stato complessivo del thread
Seleziona l'ora di avvio dell'app e guarda le sezioni dei thread complessive. Il thread principale deve essere reattivo in ogni momento.
Strumenti come Android Studio Profiler e Perfetto forniscono una panoramica dettagliata del thread principale e del tempo trascorso in ogni fase. Per saperne di più sulla visualizzazione delle tracce Perfetto, consulta la documentazione relativa alla UI di Perfetto.
Identificare i blocchi principali dello stato di sospensione del thread principale
Se il tempo trascorso in stato di sospensione è elevato, è probabile che sia dovuto al thread principale dell'app in attesa del completamento del lavoro. Se hai un'app multithread, identifica il thread su cui è in attesa il thread principale e valuta la possibilità di ottimizzare queste operazioni. Può anche essere utile per assicurarsi che non vi siano contese di blocchi non necessari che causano ritardi nel percorso critico.
Ridurre il blocco del thread principale e il sonno non interrompibile
Cerca ogni istanza del thread principale che passa allo stato bloccato. Perfetto e Studio Profiler lo mostrano con un indicatore arancione nella sequenza temporale dello stato del thread. Identifica le operazioni, verifica se sono previste o possono essere evitate e ottimizza dove necessario.
Il sonno interrompibile correlato all'I/O può rappresentare un'ottima opportunità di miglioramento. Altri processi che eseguono operazioni di I/O, anche se si tratta di app non correlate, possono competere con le operazioni di I/O eseguite dall'app principale.
Migliorare i tempi di avvio
Dopo aver identificato un'opportunità di ottimizzazione, esplora le possibili soluzioni per migliorare i tempi di avvio:
- Carica i contenuti in modo differito e asincrono per velocizzare il TTID.
- Ridurre al minimo le funzioni di chiamata che effettuano chiamate di binder. Se sono inevitabili, assicurati di ottimizzare queste chiamate memorizzando nella cache i valori anziché ripetere le chiamate o spostare il lavoro non bloccante nei thread in background.
- Per far sembrare più rapido l'avvio dell'app, puoi mostrare all'utente qualcosa che richiede un rendering minimo il più rapidamente possibile finché non viene caricato il resto della schermata.
- Crea e aggiungi un profilo di avvio alla tua app.
- Utilizza la libreria di avvio delle app Jetpack per semplificare l'inizializzazione dei componenti durante l'avvio dell'app.
Analizzare le prestazioni dell'interfaccia utente
L'avvio dell'app include una schermata iniziale e il tempo di caricamento della home page. Per ottimizzare l'avvio dell'app, esamina le tracce per capire il tempo necessario per disegnare la UI.
Limitare il lavoro durante l'inizializzazione
Il caricamento di alcuni frame potrebbe richiedere più tempo rispetto ad altri. Questi sono considerati costosi per l'app.
Per ottimizzare l'inizializzazione:
- Dai la priorità alle fasi di composizione e layout lente e scegli queste per i miglioramenti.
- Esamina ogni avviso di Perfetto e ogni avviso di Systrace aggiungendo eventi di traccia personalizzati per ridurre i disegni e i ritardi costosi.
Misurare i dati dei frame
Esistono diversi modi per misurare i dati dei frame. I cinque metodi di raccolta principali sono i seguenti:
- Raccolta locale tramite
dumpsys gfxinfo: non tutti i frame osservati nei dati dumpsys sono responsabili del rendering lento della tua app o hanno un impatto sugli utenti finali. Tuttavia, è una buona misura da esaminare nei diversi cicli di pubblicazione per comprendere la tendenza generale del rendimento. Per scoprire di più sull'utilizzo digfxinfoeframestatsper integrare le misurazioni delle prestazioni dell'UI nelle tue pratiche di test, consulta Principi di base per testare le app per Android. - Raccolta dei campi utilizzando JankStats: raccogli i tempi di rendering dei frame da parti specifiche della tua app con la libreria JankStats e registra e analizza i dati.
- Nei test che utilizzano Macrobenchmark (Perfetto sotto il cofano)
- Perfetto FrameTimeline: su Android 12 (livello API 31) o versioni successive, puoi raccogliere metriche della sequenza temporale dei frame da una traccia Perfetto per identificare quale lavoro causa l'interruzione dei frame. Questo può essere il primo passo per diagnosticare il motivo per cui i frame vengono eliminati.
- Profiler di Android Studio per il rilevamento di jank
Controllare il tempo di caricamento dell'attività principale
L'attività principale della tua app potrebbe contenere una grande quantità di informazioni
caricate da più origini. Controlla l'interfaccia utente della casa Activity e, in particolare,
l'evento Choreographer#doFrame.
- Utilizza
reportFullyDrawnper comunicare al sistema che la tua app è ora completamente disegnata a fini di ottimizzazione. - Misura l'attività e gli avvii di app utilizzando
StartupTimingMetriccon la libreria Macrobenchmark. - Osserva i cali di frame.
- Identifica i layout che richiedono molto tempo per il rendering o la misurazione.
- Identifica gli asset che richiedono molto tempo per il caricamento.
- Identifica gli elementi dell'interfaccia utente non necessari inclusi nella composizione iniziale.
Prendi in considerazione queste possibili soluzioni per ottimizzare il tempo di caricamento dell'attività principale:
- Rendi la composizione iniziale il più leggera possibile. Per ulteriori informazioni, vedi Prestazioni di Jetpack Compose.
- Aggiungi tracepoint personalizzati per fornire maggiori informazioni sui frame eliminati e sui layout complessi.
- Minimizza il numero e le dimensioni delle risorse bitmap caricate all'avvio. Per maggiori informazioni, consulta Ottimizzazione delle immagini bitmap.
Se utilizzi Jetpack Compose, valuta la possibilità di utilizzare la composizione condizionale per posticipare il caricamento delle parti dell'UI che non sono immediatamente visibili all'avvio, ad esempio schermate di errore, dettagli facoltativi o schede secondarie. Se racchiudi i componenti pesanti in un semplice controllo dello stato, eviti di eseguire la logica di composizione durante la finestra di avvio critica, mantenendo leggero il layout iniziale.
var shouldLoad by remember {mutableStateOf(false)} if (shouldLoad) { MyComposable() }Carica i composable all'interno del blocco condizionale modificando
shouldLoad:LaunchedEffect(Unit) { shouldLoad = true }Viene attivata una ricomposizione che include il codice all'interno del blocco condizionale nel primo snippet.
Per ulteriori informazioni sull'ottimizzazione delle prestazioni di Compose, consulta le best practice.
Consigliati per te
- Nota: il testo del link viene visualizzato quando JavaScript è disattivato
- Acquisire le metriche macrobenchmark
- Panoramica della misurazione delle prestazioni dell'app * Frame congelati