Gerarchie relative al rendimento e alle visualizzazioni

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:

  1. 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.
  2. Utilizza questi dati, prendendo in considerazione i pesi degli oggetti, per determinare la posizione corretta viste correlate.
  3. Esegue una seconda tessera di layout per finalizzare gli oggetti posizioni.
  4. 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 aggiungi measureWithLargestChild, 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 con Gravity classe, il vantaggio di la pre-elaborazione viene persa e il framework potrebbe dover eseguire più passaggi se è un RelativeLayout.

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.

Figura 1. Seleziona Ispeziona codice in Android Studio.

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.

Figura 2. Visualizzazione di informazioni su problemi specifici dello strumento Lint identifica.

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.