Perché alcune animazioni sono lente?

I browser moderni possono animare due proprietà CSS a basso costo: transform e opacity. Se animi qualcos'altro, è probabile che tu non riesca a raggiungere 60 f/s (frame al secondo). Questo post spiega il motivo.

È opinione diffusa che una frequenza fotogrammi di 60 FPS sia il target quando si animano elementi sul web. Questa frequenza fotogrammi garantirà la fluidità delle animazioni. Sul web, un frame è il tempo necessario per eseguire tutte le operazioni necessarie per aggiornare e ridipingere 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 in una pagina web, il browser deve seguire i seguenti passaggi sequenziali:

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

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

Quando si anima un elemento in una pagina già caricata, questi passaggi devono essere ripetuti. Questa procedura inizia dal passaggio che deve essere modificato per consentire l'animazione.

Come accennato in precedenza, questi passaggi sono sequenziali. Ad esempio, se animisci un elemento che cambia il layout, devono essere eseguiti di nuovo anche i passaggi di pittura e composizione. L'animazione di un elemento che cambia il layout è quindi più costosa dell'animazione di un elemento che cambia solo la composizione.

Animazione delle proprietà di layout

Le modifiche al layout comportano il calcolo della geometria (posizione e dimensioni) di tutti gli elementi interessati dalla modifica. Se modifichi un elemento, potrebbe essere necessario ricalcolare la geometria di altri elementi. Ad esempio, se modifichi la larghezza dell'elemento <html>, ciò potrebbe influire su tutti i suoi elementi secondari. A causa del modo in cui gli elementi si sovrappongono e si influenzano a vicenda, a volte le modifiche più in basso nell'albero possono comportare calcoli del layout fino in alto.

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

Animazione delle proprietà di verniciatura

Paint è il processo che permette di determinare in quale ordine gli elementi devono essere visualizzati sullo schermo. Spesso è l'attività che richiede più tempo di tutte quelle nella pipeline.

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

Animazione delle proprietà composite

La composizione è il processo di separazione della pagina in livelli, conversione delle informazioni relative all'aspetto della pagina in pixel (rasterizzazione) e messa in gruppo dei livelli per creare una pagina (composizione).

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

Che cos'è un livello?

Posizionando gli elementi che saranno animati o sottoposti a transizione su un nuovo livello, il browser dovrà solo rivedere questi elementi e non tutto il resto. Probabilmente conosci il concetto di livello di Photoshop, che contiene una serie di elementi che possono essere spostati insieme. I livelli di rendering del browser sono simili a questa idea.

Sebbene il browser faccia un buon lavoro nel prendere decisioni sugli elementi da posizionare su un nuovo livello, se ne manca uno, ci sono modi per forzare la creazione dei livelli. Scopri di più in Come creare animazioni ad alte prestazioni. Tuttavia, la creazione di nuovi livelli deve essere eseguita con attenzione perché ogni livello utilizza memoria. Sui dispositivi con memoria limitata, la creazione di nuovi livelli potrebbe causare un problema di prestazioni maggiore di quello che stai cercando di risolvere. Inoltre, le texture di ogni livello devono essere caricate sulla GPU. Di conseguenza, potresti riscontrare limitazioni della larghezza di banda tra la CPU e la GPU.

Rendimento CSS e JavaScript

Potresti chiederti: 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) vengono generalmente gestite in un thread noto come thread del compositore. È diverso dal thread principale del browser, in cui vengono eseguiti stile, layout, disegno e JavaScript. Ciò significa che se il browser esegue alcune attività costose sul thread principale, queste animazioni possono continuare senza essere interrotte.

Come spiegato in questo articolo, in molti casi anche altre modifiche alle trasformazioni e all'opacità possono essere gestite dal thread del compositore.

Se un'animazione attiva colorazione, layout o entrambi, il thread principale dovrà funzionare. Questo vale sia per le animazioni CSS che per quelle JavaScript. Inoltre, il sovraccarico del layout o della pittura probabilmente supererà qualsiasi lavoro associato all'esecuzione di CSS o JavaScript, rendendo la domanda irrilevante.