Come creare animazioni CSS ad alte prestazioni

Questa guida ti insegna a creare animazioni CSS ad alte prestazioni.

Consulta Perché alcune animazioni sono lente? per scoprire la teoria alla base di questi consigli.

Compatibilità del browser

Tutte le proprietà CSS consigliate in questa guida hanno un buon supporto cross-browser.

transform

Browser Support

  • Chrome: 36.
  • Edge: 12.
  • Firefox: 16.
  • Safari: 9.

Source

opacity

Browser Support

  • Chrome: 1.
  • Edge: 12.
  • Firefox: 1.
  • Safari: 2.

Source

will-change

Browser Support

  • Chrome: 36.
  • Edge: 79.
  • Firefox: 36.
  • Safari: 9.1.

Source

Spostare un elemento

Per spostare un elemento, utilizza i valori delle parole chiave translate o rotation della proprietà transform.

Ad esempio, per far scorrere un elemento nella visualizzazione, utilizza translate.

.animate {
  animation: slide-in 0.7s both;
}

@keyframes slide-in {
  0% {
    transform: translateY(-1000px);
  }
  100% {
    transform: translateY(0);
  }
}

Utilizza rotate per ruotare gli elementi. L'esempio seguente ruota un elemento di 360 gradi.

.animate {
  animation: rotate 0.7s ease-in-out both;
}

@keyframes rotate {
  0% {
    transform: rotate(0);
  }
  100% {
    transform: rotate(360deg);
  }
}

Ridimensionare un elemento

Per ridimensionare un elemento, utilizza il valore della parola chiave scale della transform proprietà.

.animate {
  animation: scale 1.5s both;
}

@keyframes scale {
  50% {
    transform: scale(0.5);
  }
  100% {
    transform: scale(1);
  }
}

Modificare la visibilità di un elemento

Per mostrare o nascondere un elemento, utilizza opacity.

.animate {
  animation: opacity 2.5s both;
}

@keyframes opacity {
  0% {
    opacity: 1;
  }
  50% {
    opacity: 0;
  }
  100% {
    opacity: 1;
  }
}

Evitare le proprietà che attivano il layout o il disegno

Prima di utilizzare qualsiasi proprietà CSS per l'animazione (oltre a transform e opacity), determina l'impatto della proprietà sulla pipeline di rendering. Evita qualsiasi proprietà che attivi il layout o il disegno, a meno che non sia assolutamente necessario.

Forzare la creazione del livello

Come spiegato in Perché alcune animazioni sono lente?, il posizionamento degli elementi su un nuovo livello consente al browser di ridisegnarli senza dover ridisegnare il resto del layout.

In genere, i browser possono prendere buone decisioni su quali elementi devono essere posizionati su un nuovo livello, ma puoi forzare manualmente la creazione del livello con la will-change proprietà. Come suggerisce il nome, questa proprietà indica al browser che l'elemento verrà modificato in qualche modo.

In CSS, puoi applicare will-change a qualsiasi selettore:

body > .sidebar {
  will-change: transform;
}

Tuttavia, la specifica suggerisce di aggiungere questa proprietà solo agli elementi che stanno per cambiare. Ad esempio, questa proprietà può essere utilizzata per una barra laterale che l'utente può far scorrere verso l'interno e l'esterno. Se l'elemento non cambia di frequente, applica will-change utilizzando JavaScript quando è probabile che si verifichi una modifica. Assicurati di dare al browser il tempo sufficiente per eseguire le ottimizzazioni necessarie e rimuovi la proprietà quando la modifica è stata interrotta.

Per forzare la creazione del livello in un browser che non supporta will-change, puoi impostare transform: translateZ(0).

Eseguire il debug di animazioni lente o con problemi

Chrome DevTools e Firefox DevTools possono aiutarti a capire perché le animazioni sono lente o con problemi.

Verificare se un'animazione attiva il layout

Un'animazione che sposta un elemento utilizzando un valore diverso da transform è probabilmente lenta. L'esempio seguente mette a confronto un'animazione che utilizza transform con un'animazione che utilizza top e left.

Cosa non fare
.box {
  position: absolute;
  top: 10px;
  left: 10px;
  animation: move 3s ease infinite;
}

@keyframes move {
  50% {
     top: calc(90vh - 160px);
     left: calc(90vw - 200px);
  }
}
Cosa fare
.box {
  position: absolute;
  top: 10px;
  left: 10px;
  animation: move 3s ease infinite;
}

@keyframes move {
  50% {
     transform: translate(calc(90vw - 200px), calc(90vh - 160px));
  }
}

Puoi testare questa funzionalità nei due esempi seguenti ed esplorare le prestazioni utilizzando DevTools.

Chrome DevTools

  1. Apri il riquadro Rendimento.
  2. Registra il rendimento di runtime durante l'animazione.
  3. Esamina la scheda Riepilogo.

Se nella scheda Riepilogo vedi un valore diverso da zero per Rendering, potrebbe significare che l'animazione sta facendo sì che il browser esegua il lavoro di layout.

Il riquadro Riepilogo mostra 37 ms per il rendering e 79 ms per il disegno.
L'esempio di animation-with-top-left causa il lavoro di rendering.
Il riquadro Riepilogo mostra valori pari a zero per il rendering e il disegno.
L'esempio di animazione con la proprietà transform non causa il lavoro di rendering.

Firefox DevTools

In Firefox DevTools, la sequenza temporale può aiutarti a capire dove il browser sta impiegando tempo.

  1. Apri il riquadro Rendimento.
  2. Avvia la registrazione del rendimento durante l'animazione.
  3. Interrompi la registrazione ed esamina la scheda Sequenza temporale.

Se vedi voci per Ricalcola stile, significa che il browser deve tornare all'inizio della sequenza temporale di rendering per eseguire il rendering dell'animazione.

Verificare la presenza di frame eliminati

  1. Apri la scheda Rendering in Chrome DevTools.
  2. Attiva la casella di controllo Indicatore FPS.
  3. Guarda i valori durante l'animazione.

Presta attenzione all'etichetta Frame nella parte superiore dell'interfaccia utente dell'indicatore FPS. Vengono visualizzati valori come 50% 1 (938 m) dropped of 1878. Un'animazione ad alte prestazioni ha una percentuale elevata, ad esempio 99%, il che significa che vengono eliminati pochi frame e l'animazione appare fluida.

Il misuratore di fps mostra che il 50% dei frame è stato eliminato
L'esempio di animazione con le proprietà animation-with-top-left causa l'eliminazione del 50% dei frame
Il misuratore di fps mostra che è stato eliminato solo l'1% dei frame
L'esempio di animazione con la proprietà transform causa l'eliminazione solo dell'1% dei frame.

Verificare se un'animazione attiva il disegno

Il disegno di alcune proprietà è più costoso per il browser rispetto ad altre. Ad esempio, qualsiasi elemento che coinvolga una sfocatura (ad esempio un'ombra) richiede più tempo per il disegno rispetto al disegno di una casella rossa. Queste differenze non sono sempre ovvie nel CSS, ma i DevTools del browser possono aiutarti a identificare le aree che devono essere ridisegnate, nonché altri problemi di prestazioni relativi al disegno.

Chrome DevTools

  1. Apri la scheda Rendering in Chrome DevTools.
  2. Seleziona Evidenziazione disegno.
  3. Sposta il puntatore sullo schermo.
Un elemento UI evidenziato in verde per dimostrare che verrà ridisegnato
In questo esempio di Google Maps, puoi vedere gli elementi che vengono ridisegnati.

Se vedi l'intero schermo lampeggiare o aree evidenziate che non ritieni debbano cambiare, approfondisci la questione.

Se devi determinare se una determinata proprietà sta causando problemi di prestazioni relativi al disegno, il profiler di disegno in Chrome DevTools può aiutarti.

Firefox DevTools

  1. Apri Impostazioni e aggiungi un pulsante della barra degli strumenti per attivare/disattivare l'evidenziazione del disegno.
  2. Nella pagina che vuoi esaminare, attiva il pulsante e sposta il mouse o scorri per visualizzare le aree evidenziate.

Animare nella fase di composizione

Se possibile, limita le animazioni a opacity e transform per mantenerle nella fase di composizione del percorso di rendering. Utilizza DevTools per verificare quale fase del percorso è interessata dalle animazioni.

Utilizza il profiler di disegno per verificare se alcune operazioni di disegno sono particolarmente costose. Se trovi qualcosa, verifica se una proprietà CSS diversa offre lo stesso aspetto con prestazioni migliori.

Utilizza la proprietà will-change con parsimonia e solo se riscontri un problema di prestazioni.