Perché alcune animazioni sono lente?

I browser moderni possono animare due proprietà CSS in modo economico: transform e opacity. Se anima qualcos'altro, è probabile che i 60 frame al secondo (f/s) non siano perfettamente fluidi. Questo post spiega il motivo di questa scelta.

Prestazioni dell'animazione e frequenza fotogrammi

È ampiamente accettato che l'obiettivo dell'animazione di qualsiasi cosa sul web sia una frequenza fotogrammi di 60 FPS. Questa frequenza fotogrammi garantirà che le animazioni risultino fluide. Sul web un frame è il tempo necessario per svolgere tutto il lavoro necessario per aggiornare e colorare lo schermo. Se ogni frame non viene completato entro 16,7 ms (1000 ms / 60 ≈ 16,7), gli utenti percepiranno il ritardo.

La pipeline di rendering

Per visualizzare qualcosa su una pagina web, il browser deve svolgere i seguenti passaggi sequenziali:

  1. Stile: calcola gli stili da applicare agli elementi.
  2. Layout: genera la geometria e la posizione per ogni elemento.
  3. Colora: compila i pixel di ogni elemento nei livelli.
  4. Composito: disegna i livelli sullo schermo.

Questi quattro passaggi sono noti come pipeline di rendering del browser.

Quando anima un elemento in una pagina già caricata, questi passaggi devono ripetere l'animazione. Questo processo inizia dal passaggio che deve essere modificato per consentire l'esecuzione dell'animazione.

Come accennato prima, questi passaggi sono sequenziali. Ad esempio, se aggiungi un'animazione a un elemento che cambia il layout, anche i passaggi di colorazione e composito devono essere eseguiti di nuovo. Di conseguenza, l'animazione di un elemento che cambia il layout è più costosa rispetto a quella di un elemento che cambia solo la composizione.

Animazione delle proprietà del layout

Le modifiche al layout prevedono il calcolo della geometria (posizione e dimensione) di tutti gli elementi interessati dalla modifica. Se modifichi un elemento, potrebbe essere necessario ricalcolare la geometria di altri elementi. Ad esempio, la modifica della larghezza dell'elemento <html> potrebbe avere un impatto su tutti gli elementi secondari. A causa del modo in cui gli elementi si sovraccaricano e influiscono l'uno sull'altro, le modifiche più in basso nell'albero possono a volte comportare calcoli del layout fino alla cima.

Più grande è l'albero degli elementi visibili, più tempo occorre per i calcoli del layout.

Animazione delle proprietà di colorazione

La dipintura è il processo che consente di determinare l'ordine in cui gli elementi devono essere dipinti sullo schermo. È spesso l'attività più lunga di tutte le attività nella pipeline.

La maggior parte delle operazioni di colorazione nei browser moderni viene eseguita in rasterizzatori software. A seconda di come gli elementi nella tua app sono raggruppati in livelli, potrebbe essere necessario colorare anche altri elementi oltre a quello modificato.

Animazione delle proprietà composte

La composizione è il processo di separazione della pagina in livelli, conversione delle informazioni sull'aspetto della pagina in pixel (rasterizzazione) e unione dei livelli per creare una pagina (compositing).

Questo è il motivo per cui la proprietà opacity è inclusa nell'elenco di elementi economici da animare. Finché questa proprietà si trova nel suo livello, le modifiche possono essere gestite dalla GPU durante il passaggio di composizione. I browser basati su Chromium e WebKit creano un nuovo livello per qualsiasi elemento con una transizione o un'animazione CSS su opacity.

Che cos'è un livello?

Posizionando gli elementi che verranno animati o trasferiti a un nuovo livello, il browser dovrà ridipingere solo quegli elementi e non tutto il resto. Probabilmente hai già familiarità con il concetto di Photoshop di un livello che contiene un gruppo di elementi che possono essere spostati insieme. I livelli di rendering del browser sono simili a questa idea.

Anche se il browser fa un buon lavoro nel prendere decisioni in merito agli elementi da collocare su un nuovo livello, se ne manca uno ci sono dei modi per forzare la creazione di un livello. Puoi scoprirlo in Come creare animazioni ad alte prestazioni. Tuttavia, la creazione di nuovi livelli deve essere eseguita con attenzione, poiché ogni livello utilizza memoria. Sui dispositivi con memoria limitata, la creazione di nuovi livelli può causare un problema di prestazioni più elevato rispetto a quello che stai tentando di risolvere. Inoltre, le texture di ogni livello devono essere caricate nella GPU. Pertanto, potresti raggiungere dei limiti di larghezza di banda tra CPU e GPU.

Rendimento CSS e JavaScript

Potresti chiederti se dal punto di vista del rendimento è meglio utilizzare CSS o JavaScript per le animazioni?

Le animazioni basate su CSS e le animazioni web (nei browser che supportano l'API) sono generalmente gestite in un thread noto come thread composito. È diverso dal thread principale del browser, dove vengono eseguiti stile, layout, disegno e JavaScript. Ciò significa che se il browser esegue attività costose sul thread principale, queste animazioni possono continuare senza essere interrotte.

Come spiegato in questo articolo, in molti casi anche le altre modifiche apportate a trasformazioni e opacità possono essere gestite dal thread del compositore.

Se un'animazione attiva la colorazione, il layout o entrambi, il thread principale dovrà funzionare. Questo vale sia per le animazioni CSS che per JavaScript e l'overhead del layout o della colorazione probabilmente supererà qualsiasi lavoro associato all'esecuzione di CSS o JavaScript, mostrando il moot della domanda.