Il modo in cui gestisci la gerarchia
View
oggetti possono avere un impatto significativo
il rendimento della tua app. In questa pagina viene descritto come valutare se la gerarchia delle visualizzazioni sta rallentando.
la tua app e offre alcune strategie per risolvere eventuali problemi.
Questa pagina è incentrata sul miglioramento dei layout basati su View
. Per informazioni su come migliorare
Prestazioni di Jetpack Compose, vedi Jetpack Compose
del rendimento.
Progetta e misura il rendimento
La pipeline di rendering include una fase di tipo layout-and-measure, durante la quale il sistema
posiziona in modo appropriato gli elementi pertinenti nella gerarchia di visualizzazione. La parte relativa alla misura
determina le dimensioni e i confini di View
oggetti. La parte layout
determina dove posizionare gli oggetti View
sullo schermo.
Entrambe queste fasi della pipeline comportano un basso costo per visualizzazione o layout elaborati. La maggior parte di
nel corso del tempo, questo costo è minimo e non influisce in modo significativo sulle prestazioni. Tuttavia, il valore può essere maggiore
quando un'app aggiunge o rimuove View
oggetti, ad esempio quando un
RecyclerView
li ricicla o li riutilizza. Il costo può essere superiore anche se un oggetto View
deve
prendere in considerazione il ridimensionamento
per soddisfare i suoi vincoli. Ad esempio, se la tua app chiama
SetText()
su un oggetto View
che aggrega il testo, potrebbe essere necessario ridimensionare View
.
Se questi casi richiedono troppo tempo, possono impedire il rendering di un frame all'interno dell'intervallo 16 ms, che possono causare interruzioni dei frame e rendere l'animazione fluida.
Poiché non puoi spostare queste operazioni in un thread di lavoro, la tua app deve elaborarle su thread principale, è meglio ottimizzarli in modo che richiedano il minor tempo possibile.
Gestire layout complessi
I Layout Android ti consentono di nidificare gli oggetti UI la gerarchia delle visualizzazioni. La nidificazione può anche comportare un costo per il layout. Quando la tua app elabora un oggetto per il layout, l'app esegue la stessa procedura anche su tutti gli elementi secondari del layout.
Per un layout complicato, a volte un costo si verifica solo la prima volta che il sistema calcola
layout. Ad esempio, quando la tua app ricicla un elemento dell'elenco complesso in un RecyclerView
, il sistema deve disporre tutti gli oggetti. In un altro esempio, modifiche basilari possono
si propagano lungo la catena verso l'elemento padre finché non raggiungono un oggetto che non influisce sulla dimensione
l'elemento principale.
Un motivo comune per cui il layout richiede molto tempo è la presenza di gerarchie di oggetti View
sono nidificate l'una nell'altra. Ogni oggetto di layout nidificato aggiunge un costo alla fase di layout. Migliore
meno tempo necessario per il completamento della fase di layout.
Ti consigliamo di utilizzare
Editor del layout per creare un
ConstraintLayout
, anziché
RelativeLayout
o
LinearLayout
,
in generale è più efficiente e riduce la nidificazione dei layout. Tuttavia, nel caso di layout semplici
che può essere ottenuta utilizzando
FrameLayout
, ti consigliamo
utilizzando FrameLayout
.
Se utilizzi il corso RelativeLayout
, potresti essere in grado di ottenere lo stesso
a un costo inferiore usando invece LinearLayout
visualizzazioni nidificate e non ponderate. Tuttavia,
se utilizzi visualizzazioni LinearLayout
ponderate e nidificate, il costo del layout è molto più elevato
perché richiede più passaggi di layout, come spiegato nella prossima sezione.
Ti consigliamo anche di utilizzare RecyclerView
anziché
ListView
, in quanto può riciclare
layout di singoli elementi dell'elenco, in modo che sia più efficiente e può migliorare lo scorrimento
le prestazioni dei dispositivi.
Doppia imposizione
In genere, il framework esegue la fase di layout o misurazione in un unico passaggio. Tuttavia, con casi di layout complessi, il framework potrebbe dover ripetere più volte una gerarchia di contenuti che richiedono più passaggi per essere risolti prima di posizionare gli elementi. Avere eseguire più di un'iterazione di layout e misurazione è detta doppia fiscale.
Ad esempio, quando utilizzi il contenitore RelativeLayout
, che ti consente di posizionare
View
oggetti rispetto alle posizioni degli altri View
oggetti, l'oggetto
il framework esegue la seguente sequenza:
- Esegue un passaggio di layout e misurazione, durante il quale il framework calcola il parametro posizione e dimensione, in base alla richiesta di ogni figlio.
- Utilizza questi dati, prendendo in considerazione i pesi degli oggetti, per determinare la posizione corretta viste correlate.
- Esegue una seconda tessera di layout per finalizzare gli oggetti posizioni.
- Passa alla fase successiva del processo di rendering.
Maggiore è il numero di livelli della gerarchia delle visualizzazioni, maggiore sarà il potenziale di peggioramento del rendimento.
Come accennato in precedenza, ConstraintLayout
è generalmente più efficiente di altri
layout tranne FrameLayout
. È meno soggetto a più passaggi di layout e in molti
elimina la necessità di nidificare i layout.
Anche i container diversi da RelativeLayout
potrebbero aumentare la doppia tassazione. Per
esempio:
- Una vista
LinearLayout
può comportare una doppia verifica del layout e della misurazione se effettui orizzontale. Un doppio passaggio di layout e misurazione può verificarsi anche in orientamento verticale se aggiungimeasureWithLargestChild
, in questo caso il framework potrebbe dover eseguire un secondo passaggio per risolvere le dimensioni di oggetti strutturati. - Inoltre,
GridLayout
consente un posizionamento relativo, ma di solito evita la doppia tassazione grazie alla pre-elaborazione relazioni posizionali tra le visualizzazioni figlio. Tuttavia, se il layout utilizza ponderazioni o riempimento conGravity
classe, il vantaggio di la pre-elaborazione viene persa e il framework potrebbe dover eseguire più passaggi se è unRelativeLayout
.
Più passaggi di layout e misurazione non rappresentano necessariamente un onere in termini di rendimento. Tuttavia, possono diventano un onere se si trovano nel posto sbagliato. Fai attenzione alle situazioni in cui uno dei seguenti al container si applicano alle seguenti condizioni:
- È un elemento radice della gerarchia delle visualizzazioni.
- Al di sotto è presente una gerarchia di visualizzazione approfondita.
- Ci sono molti casi in cui si completano lo schermo, simili ai bambini in una
ListView
oggetto.
Diagnosticare i problemi relativi alla gerarchia delle visualizzazioni
Le prestazioni del layout sono un problema complesso con molti facet. I seguenti strumenti possono aiutarti identificare dove si verificano i colli di bottiglia delle prestazioni. Alcuni strumenti forniscono informazioni meno definitive ma può fornire suggerimenti utili.
Perfetto
Perfetto è uno strumento che fornisce dati sulle prestazioni. Puoi aprire le tracce Android nel Perfetto interfaccia utente.
Traccia prof. render. GPU
Il rendering delle GPU del profilo sul dispositivo disponibile sui dispositivi con sistema operativo Android 6.0 (livello API 23) e versioni successive, può fornirti le e informazioni concrete sui colli di bottiglia delle prestazioni. Questo strumento ti consente di vedere per quanto tempo layout-e-misurazione sta prendendo per ciascuno frame del rendering. Questi dati possono aiutarti a diagnosticare i problemi di prestazioni del runtime e determinare i problemi di layout e misurazione da risolvere.
Nella rappresentazione grafica dei dati acquisiti, il rendering GPU Profile utilizza il colore blu per indicare l'ora del layout. Per ulteriori informazioni su come utilizzare questo strumento, vedi Velocità di rendering della GPU del profilo.
Pelucchi
Lo strumento Lint di Android Studio può aiutarti a farti un'idea inefficienze nella gerarchia delle visualizzazioni. Per utilizzare questo strumento, seleziona Analizza > Ispeziona codice, come mostrato nella figura 1.
Le informazioni sui vari elementi di layout vengono visualizzate in Android > Pelucchi > Prestazioni. Per visualizzare maggiori dettagli, fai clic su ciascun elemento per espanderlo e visualizzare ulteriori informazioni nel riquadro al sul lato destro dello schermo. La figura 2 mostra un esempio di informazioni espanse.
Facendo clic su un elemento, vengono visualizzati i problemi associati nel riquadro a destra.
Per saperne di più su argomenti e problemi specifici in quest'area, consulta la Lint.
Layout Inspector
Lo strumento Layout Inspector di Android Studio una rappresentazione visiva della gerarchia delle visualizzazioni dell'app. È un buon modo per esplorare la gerarchia della tua app, fornendo una chiara rappresentazione visiva della catena principale di una determinata vista, e ti consente ed esaminare i layout creati dalla tua app.
Le viste presentate da Layout Inspector possono inoltre essere utili per identificare i problemi di rendimento derivanti doppia tassazione. Può anche fornire un modo per identificare profonde catene di layout nidificati. aree di layout con una grande quantità di elementi secondari nidificati, che possono essere una fonte di costi per le prestazioni. Nella in questi casi, le fasi di layout e misurazione possono essere costose e generare problemi di prestazioni.
Per ulteriori informazioni, consulta Eseguire il debug del layout con Layout Inspector e Convalida dei layout.
Risolvere i problemi relativi alla gerarchia delle visualizzazioni
Il concetto fondamentale alla base della risoluzione dei problemi di prestazioni che nascono dalle gerarchie di vista può essere difficile nella pratica. Impedire che le gerarchie di visualizzazioni impongano penalità per le prestazioni consiste di appiattire la gerarchia delle visualizzazioni e ridurre la doppia tassazione. Questa sezione illustra le strategie per il perseguimento di questi obiettivi.
Rimuovi i layout nidificati ridondanti
ConstraintLayout
è una libreria Jetpack con un gran numero di meccanismi diversi per posizionare le viste all'interno
layout. In questo modo si riduce la necessità di nidificare un ConstaintLayout
e può contribuire ad appiattire la visuale
nella gerarchia. Di solito è più semplice unire le gerarchie utilizzando ConstraintLayout
rispetto
ad altri tipi di layout.
Gli sviluppatori spesso usano layout nidificati più del necessario. Ad esempio, un
Il container RelativeLayout
potrebbe contenere un singolo elemento secondario che è anche un
RelativeLayout
contenitore. Questa nidificazione è ridondante e aggiunge costi superflui
la gerarchia di visualizzazione. Lint può segnalare questo problema per te, riducendo i tempi di debug.
Adotta l'unione o l'inclusione
Una causa frequente dei layout nidificati ridondanti è la presenza di
<include>
del tag. Ad esempio, puoi definire un layout riutilizzabile come segue:
<LinearLayout> <!-- some stuff here --> </LinearLayout>
Potresti quindi aggiungere un tag <include>
per aggiungere il seguente elemento all'elemento principale
contenitore:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent" android:background="@color/app_bg" android:gravity="center_horizontal"> <include layout="@layout/titlebar"/> <TextView android:layout_width="match_parent" android:layout_height="wrap_content" android:text="@string/hello" android:padding="10dp" /> ... </LinearLayout>
Il precedente include nidifica inutilmente il primo layout all'interno del secondo.
La
<merge>
può aiutare a evitare questo problema. Per informazioni su questo tag, consulta
Utilizzare l'elemento <unione>
del tag.
Adotta un layout più economico
Potresti non essere in grado di modificare lo schema di layout esistente in modo che non contenga elementi layout. In alcuni casi, l'unica soluzione potrebbe essere appiattire la gerarchia passando un tipo di layout completamente diverso.
Ad esempio, potresti notare che
TableLayout
fornisce lo stesso
come un layout più complesso con molte dipendenze di posizionamento. La biblioteca Jetpack
ConstraintLayout
offre una funzionalità simile a RelativeLayout
, oltre ad altre per aiutare a creare
layout più semplici ed efficienti.