Come creare animazioni CSS ad alte prestazioni

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

Consulta l'articolo Perché alcune animazioni sono lente? per conoscere la teoria alla base di questi consigli.

Tutte le proprietà CSS consigliate in questa guida hanno un buon supporto su più browser.

transform

Supporto dei browser

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

Origine

opacity

Supporto dei browser

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

Origine

will-change

Supporto dei browser

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

Origine

Spostare un elemento

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

Ad esempio, per visualizzare un elemento tramite scorrimento, 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 proprietà transform.

.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;
 
}
}

Evita proprietà che attivano il layout o la pittura

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

Forzare la creazione del livello

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

In genere i browser sono in grado di prendere decisioni oculate sugli elementi da posizionare su un nuovo livello, ma puoi forzare manualmente la creazione dei livelli con la proprietà will-change. Come suggerisce il nome, questa proprietà indica al browser che questo 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 farlo solo per gli elementi che sono sempre in procinto di subire modifiche. Ad esempio, potrebbe essere il caso di una barra laterale che l'utente può far scorrere. Per gli elementi che non cambiano di frequente, consigliamo di applicare will-change utilizzando JavaScript quando è probabile che si verifichi una modifica. Assicurati di concedere al browser il tempo sufficiente per eseguire le ottimizzazioni necessarie e di rimuovere la proprietà una volta interrotta la modifica.

Se vuoi forzare la creazione di un livello in un browser che non supporta will-change (molto probabilmente Internet Explorer), puoi impostare transform: translateZ(0).

Eseguire il debug di animazioni lente o con glitch

Gli Strumenti per sviluppatori di Chrome e Firefox includono molti strumenti per aiutarti a capire perché le animazioni sono lente o presentano dei bug.

Controllare se un'animazione attiva il layout

Un'animazione che sposta un elemento utilizzando qualcosa di diverso da transform è probabile che sia lenta. L'esempio seguente confronta 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 di Glitch ed esplorare le prestazioni con DevTools.

Chrome DevTools

  1. Apri il riquadro Rendimento.
  2. Registra le prestazioni di runtime durante l'animazione.
  3. Controlla la scheda Riepilogo.

Se nella scheda Riepilogo viene visualizzato un valore diverso da zero per Rendering, è possibile che l'animazione stia facendo eseguire il layout del browser.

Il riquadro Riepilogo mostra 37 ms per il rendering e 79 ms per la pittura.
L'esempio animation-with-top-left comporta il rendering.
Il riquadro Riepilogo mostra valori zero per il rendering e la pittura.
L'esempio animation-with-transform non comporta operazioni di rendering.

DevTools di Firefox

In Strumenti per gli sviluppatori di Firefox, la cascata 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 e controlla la scheda Flusso.

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

Controlla la presenza di frame persi

  1. Apri la scheda Rendering in Chrome DevTools.
  2. Attiva la casella di controllo Tasto FPS.
  3. Osserva i valori durante l'esecuzione dell'animazione.

Fai attenzione all'etichetta Frame nella parte superiore dell'interfaccia utente del misuratore FPS. Vengono visualizzati valori come 50% 1 (938 m) dropped of 1878. Un'animazione ad alte prestazioni ha un'alta percentuale, come 99%, il che significa che vengono eliminati alcuni frame e l'animazione risulta uniforme.

Il misuratore di frame al secondo indica che il 50% dei frame è stato perso
L'esempio animation-with-top-left comporta l'eliminazione del 50% dei frame
Il misuratore di frame al secondo indica che solo l'1% dei frame è stato perso
L'esempio animation-with-transform comporta l'eliminazione di solo l'1% dei frame.

Controlla se un'animazione attiva la pittura

Alcune proprietà sono più costose di altre da visualizzare nel browser. Ad esempio, qualsiasi elemento che prevede una sfocatura (ad esempio un'ombra) richiede più tempo per essere dipinto rispetto a un riquadro rosso. Queste differenze non sono sempre evidenti nel CSS, ma gli strumenti di sviluppo del browser possono aiutarti a identificare le aree che devono essere ridisegniate, nonché altri problemi di prestazioni relativi alla pittura.

Chrome DevTools

  1. Apri la scheda Rendering in Chrome DevTools.
  2. Seleziona Vernice lampeggiante.
  3. Sposta il cursore sullo schermo.
Un elemento dell'interfaccia utente evidenziato in verde per dimostrare che verrà ridisegnato
In questo esempio tratto da Google Maps, puoi vedere gli elementi che vengono ridipingiti.

Se vedi l'intero schermo lampeggiare o aree evidenziate che non ritieni dovrebbero cambiare, indaga ulteriormente.

Se devi determinare se una determinata proprietà causa problemi di prestazioni relativi alla pittura, il profilatore di pittura in Chrome DevTools può aiutarti.

DevTools di Firefox

  1. Apri Impostazioni e aggiungi un pulsante della cassetta degli attrezzi per Attiva/disattiva lampeggio del colore.
  2. Nella pagina che vuoi ispezionare, attiva il pulsante e muovi il mouse o scorri per visualizzare le aree evidenziate.

Conclusione

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 pittura per verificare se le operazioni di pittura sono particolarmente costose. Se ne trovi, controlla se una proprietà CSS diversa offre lo stesso aspetto e un rendimento migliore.

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