Come creare animazioni CSS ad alte prestazioni

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

Consulta la sezione 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 offrono un buon supporto tra browser.

Spostare un elemento

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

Ad esempio, per rendere visibile un elemento, utilizza translate.

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

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

Anche gli elementi possono essere ruotati, nell'esempio sotto a 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 le proprietà che attivano il layout o la colorazione

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

Forza creazione livelli

Come spiegato nella sezione Perché alcune animazioni sono lente?, posizionando gli elementi su un nuovo livello, è possibile ricolorare le animazioni senza che sia necessario colorare anche il resto del layout.

I browser spesso prendono decisioni corrette in merito a quali elementi devono essere posizionati in un nuovo livello, ma puoi forzare manualmente la creazione di un livello con la proprietà will-change. Come suggerisce il nome, questa proprietà indica al browser che in qualche modo l'elemento verrà modificato.

Nel CSS questa proprietà può essere applicata a qualsiasi selettore:

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

Tuttavia, la specifica suggerisce che questo approccio debba essere adottato solo per gli elementi che sono sempre in procinto di cambiare. Se l'esempio precedente fosse una barra laterale, l'utente potrebbe scorrere dentro e fuori la pagina, questo potrebbe essere il caso. Poiché alcuni elementi della pagina potrebbero non cambiare di frequente, sarebbe meglio applicare will-change utilizzando JavaScript in un momento in cui potrebbe verificarsi la modifica. Dovrai assicurarti di concedere al browser il tempo necessario per eseguire le ottimizzazioni necessarie, poi rimuovere la proprietà dopo aver interrotto la modifica.

Se hai bisogno di un modo per forzare la creazione di livelli in uno dei rari browser che non supportano will-change (molto probabilmente Internet Explorer a questo punto), puoi impostare transform: translateZ(0).

Esegui il debug di animazioni lente o scadenti

Chrome DevTools e Firefox DevTools hanno molti strumenti per aiutarti a capire perché le animazioni sono lente o scadenti.

Controllare se un'animazione attiva il layout

Un'animazione che sposta un elemento utilizzando un elemento diverso da transform probabilmente sarà lenta. Nel seguente esempio, ho ottenuto lo stesso risultato visivo animando top e left e utilizzando transform.

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 di Glitch seguenti ed esplorare le prestazioni con DevTools.

Chrome DevTools

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

Se vedi un valore diverso da zero per Rendering nella scheda Riepilogo, è possibile che l'animazione sia la causa del funzionamento del layout da parte del browser.

Il riquadro Riepilogo mostra 37 ms per il rendering e 79 ms per la pittura.
L'esempio animation-with-top-left causa il lavoro di 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 Firefox DevTools, la funzionalità Struttura a cascata può aiutarti a capire su quali pagine del browser trascorre il tempo.

  1. Apri il riquadro Rendimento.
  2. Nel riquadro Inizia a registrare prestazioni mentre è in corso l'animazione.
  3. Interrompi la registrazione e controlla la scheda Cascata.

Se vedi voci per Ricalcola stile, il browser deve iniziare dall'inizio della struttura a cascata di rendering.

Controllare se un'animazione sta perdendo frame

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

Nella parte superiore dell'interfaccia utente dello strumento di misurazione fPS trovi l'etichetta Frame. Sotto vedi un valore lungo le righe 50% 1 (938 m) dropped of 1878. Un'animazione ad alte prestazioni avrà una percentuale elevata, ad esempio 99%. Una percentuale elevata indica che vengono eliminati alcuni fotogrammi e l'animazione risulterà uniforme.

L'indicatore di FPS mostra che il 50% dei frame è stato perso
L'esempio animation-with-top-left causa l'eliminazione del 50% dei frame
Lo strumento di misurazione fps mostra che solo l'1% dei frame è stato perso
L'esempio animation-with- transform causa l'eliminazione solo dell'1% dei frame.

Controllare se un'animazione attiva la colorazione

Quando si parla di dipingere, alcune cose sono più costose di altre. Ad esempio, tutto ciò che comporta una sfocatura (come un'ombra) impiegherà più tempo per dipingere rispetto a disegnare un riquadro rosso. In termini di CSS, tuttavia, questo non è sempre ovvio: background: red; e box-shadow: 0, 4px, 4px, rgba(0,0,0,0.5); non sembrano necessariamente avere caratteristiche di rendimento molto diverse, ma sì.

Strumenti per sviluppatori del browser può aiutarti a identificare le aree da rivedere e i problemi di prestazioni relativi alla colorazione.

Chrome DevTools

  1. Apri la scheda Rendering di Chrome DevTools.
  2. Seleziona Lampeggiamento di pittura.
  3. Sposta il puntatore sullo schermo.
Un elemento UI evidenziato in verde per dimostrare che verrà ridipinto
In questo esempio tratto da Google Maps puoi vedere gli elementi che verranno ridipinti.

Se vedi che l'intero schermo lampeggia o sono evidenziate aree che ritieni non debbano cambiare, prova a fare qualche ricerca.

Se devi analizzare in dettaglio se una determinata proprietà causa problemi di prestazioni dovuti alla colorazione, lo strumento paint profiler in Chrome DevTools può esserti di aiuto.

Firefox DevTools

  1. Apri Impostazioni e aggiungi un pulsante degli strumenti per Attiva/disattiva lampeggiamento della vernice.
  2. Nella pagina che vuoi ispezionare, attiva il pulsante e sposta il mouse oppure 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 profilatore per la vernice per vedere se le operazioni di verniciatura sono particolarmente costose. Se noti qualcosa, verifica se una proprietà CSS diversa garantirà lo stesso aspetto e un rendimento migliore.

Utilizza la proprietà will-change con parsimonia e solo in caso di problemi di prestazioni.