Come evitare vernici non necessarie - Edizione GIF animata

Paul Lewis

Evitare le pitture è fondamentale per ottenere una frequenza frame fluida, in particolare sui dispositivi mobili. A volte, però, le pitture appaiono nei luoghi più insoliti. Questo articolo spiega perché le GIF animate possono causare la generazione di pitture non necessarie e la soluzione sorprendentemente semplice che puoi applicare.

Strati di bellezza

Come probabilmente saprai, i browser moderni possono dipingere gruppi di elementi DOM in "immagini" separate, chiamate livelli. A volte c'è un livello per l'intera pagina, a volte ce ne sono centinaia o, in rari casi, migliaia.

Quando gli elementi DOM sono raggruppati in un livello e uno degli elementi cambia visivamente, dobbiamo dipingere non solo l'elemento modificato, ma anche tutti gli altri elementi del livello che si sovrappongono all'elemento modificato. Se dipingi un elemento sopra un altro, i pixel sovrascritti vengono effettivamente "persi" per sempre. Se vuoi ripristinare i pixel originali, devi dipingerli di nuovo.

A volte, quindi, vogliamo isolare un elemento dagli altri in modo che, quando viene dipinto, non sia necessario ridipingere gli altri elementi che non sono cambiati. Ad esempio, quando combini un'intestazione di pagina fissa con contenuti scorrevoli, devi ridipingere l'intestazione ogni volta che i contenuti scorrono, nonché i contenuti appena visibili. Posizionando l'intestazione in un livello separato, il browser può ottimizzare lo scorrimento. Quando scorri, il browser può spostare i livelli, probabilmente con l'aiuto della GPU, ed evitare di ridipingere uno dei due livelli.

Ogni livello aggiuntivo aumenta il consumo di memoria e aggiunge un overhead alle prestazioni, quindi l'obiettivo è raggruppare la pagina nel minor numero possibile di livelli mantenendo buone prestazioni.

Che cosa c'entra tutto questo con le GIF animate?

Diamo un'occhiata a questa foto:

Un'app web suddivisa in quattro livelli.
Figura 1: un'app web suddivisa in quattro livelli.

Questa è una potenziale configurazione dei livelli per un'app semplice. Sono presenti quattro livelli: tre (livelli 2-4) sono elementi di interfaccia; il livello di fondo è un caricamento, che in questo caso è una GIF animata. Nel flusso normale, mostri il caricatore (livello 1) durante il caricamento dell'app, quindi, al termine di tutto, mostri gli altri livelli. Ma ecco il punto chiave: devi nascondere la GIF animata.

Ma perché devo nasconderlo?

Ottima domanda. In un mondo perfetto, il browser controllerebbe semplicemente la visibilità della GIF ed eviterebbe di dipingere automaticamente. Purtroppo, verificare se la GIF animata è oscurata o visibile sullo schermo è in genere più costoso che dipingerla, quindi viene dipinta.

Nel migliore dei casi, la GIF si trova in un proprio livello e il browser deve solo dipingerla e caricarla sulla GPU. Nel peggiore dei casi, tutti gli elementi potrebbero essere raggruppati in un unico livello e il browser deve ridisegnare ogni singolo elemento. Al termine, deve comunque caricare tutto sulla GPU. Tutto questo lavoro viene eseguito per ogni frame della GIF, nonostante l'utente non possa nemmeno vedere la GIF.

Sui computer probabilmente puoi cavartela con questo tipo di comportamento di disegno perché le CPU e le GPU sono più potenti e c'è molta larghezza di banda per il trasferimento dei dati tra le due. Tuttavia, sui dispositivi mobili la pittura è estremamente costosa, quindi devi fare molta attenzione.

Quali browser sono interessati?

Come spesso accade, i comportamenti variano da un browser all'altro. Attualmente, Chrome, Safari e Opera ridipingono tutti, anche se la GIF è oscurata. Firefox, invece, capisce che la GIF è oscurata e non deve essere ridipinta. Internet Explorer rimane una sorta di scatola nera e, anche in IE11, poiché gli strumenti F12 sono ancora in fase di sviluppo, non è possibile sapere se è in corso o meno una nuova colorazione.

Come faccio a sapere se ho questo problema?

Il modo più semplice è utilizzare "Mostra rettangoli di pittura" in Chrome DevTools. Carica DevTools e premi l'icona a forma di ingranaggio nell'angolo in basso a destra (Icona a forma di ingranaggio) e scegli Mostra rettangoli di pittura nella sezione Rendering.

Attivare Mostra rettangoli colorati all'interno di Chrome DevTools
Figura 2: attivazione di Mostra rettangoli di pittura in Chrome DevTools.

Ora non devi fare altro che cercare un rettangolo rosso come questo:

Lo strumento Mostra i rettangoli colorati di DevTools suggerisce problemi con le GIF animate con un rettangolo rosso.
Figura 3: l'opzione Mostra rettangoli di pittura di DevTools suggerisce problemi con le GIF animate con un rettangolo rosso.

La piccola casella rossa sullo schermo indica che Chrome sta ridisegnando qualcosa. Sappi che c'è una GIF di caricamento nascosta dietro gli altri elementi, quindi quando vedi una casella rossa come questa devi nascondere gli elementi visibili e controllare se hai lasciato la GIF animata in esecuzione. In questo caso, devi inserire del codice CSS o JavaScript per applicare display: none o visibility: hidden all'elemento o al suo elemento principale. Ovviamente, se si tratta solo di un'immagine di sfondo, devi assicurarti di rimuoverla.

Se vuoi vedere un esempio di questo comportamento in un sito attivo, dai un'occhiata ad Allegro, dove l'immagine di ogni prodotto ha una GIF di caricamento oscurata anziché nascosta esplicitamente.

Conclusione

Per raggiungere i 60 fps, devi fare solo ciò che è necessario per eseguire il rendering della pagina e non di più. La rimozione delle vernici in eccesso è un passaggio fondamentale per raggiungere questo obiettivo. Le GIF animate lasciate in esecuzione possono attivare colorazioni non necessarie, che puoi trovare e analizzare facilmente con lo strumento Mostra rettangoli colorati di DevTools.

Non hai lasciato in esecuzione per sempre la GIF animata del gattino di caricamento, vero?