Come creare animazioni CSS ad alte prestazioni

Questa guida spiega come creare animazioni CSS ad alte prestazioni.

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

Compatibilità del browser

Tutte le proprietà CSS consigliate in questa guida hanno un buon supporto su più 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 in vista, utilizza translate.

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

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

Usa 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 in Perché alcune animazioni sono lente?, collocare gli elementi in un nuovo livello consente al browser di ridipingerli senza dover ridipingere il resto del layout.

In genere i browser possono prendere buone decisioni su quali elementi posizionare su un nuovo livello, ma puoi forzare manualmente la creazione del livello 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 aggiungerlo solo agli elementi che sono sempre in procinto di subire modifiche. Ad esempio, può essere utilizzato per una barra laterale che l'utente può far scorrere. Se l'elemento non cambia spesso, applica will-change utilizzando JavaScript quando è probabile che si verifichi una modifica. Assicurati di concedere al browser tempo sufficiente per eseguire le ottimizzazioni necessarie e rimuovi la proprietà quando la modifica è stata interrotta.

Per forzare la creazione di un livello in un browser senza il supporto di will-change, puoi impostare transform: translateZ(0).

Eseguire il debug di animazioni lente o con glitch

Chrome DevTools e Firefox DevTools possono aiutarti a capire perché le animazioni sono lente o presentano dei bug.

Verificare 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 testarlo nei due esempi riportati di seguito e analizzare le prestazioni utilizzando 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.

Firefox DevTools

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 di 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 persi pochi frame e l'animazione sembra fluida.

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 da dipingere per il browser rispetto ad altre. Ad esempio, qualsiasi elemento che prevede una sfocatura (ad esempio un'ombra) richiede più tempo per essere disegnato 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 di Google Maps, puoi vedere gli elementi che vengono ridipinti.

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.

Firefox DevTools

  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.

Animare nella fase composita

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 rendimento.