Verso una metrica di fluidità dell'animazione

Scopri di più sulla misurazione delle animazioni, sui frame di animazione e sulla fluidità generale delle pagine.

Behdad Bakhshinategh
Behdad Bakhshinategh
Jonathan Ross
Jonathan Ross
Michal Mocny
Michal Mocny

Probabilmente hai notato pagine che "stuttering" o "blocca" durante lo scorrimento le animazioni. Ci piace dire che queste esperienze non sono fluide. Indirizzo di destinazione di questo tipo di problemi, il team di Chrome sta lavorando per aggiungere ulteriore supporto agli strumenti del lab per il rilevamento delle animazioni, oltre ad apportare miglioramenti costanti alla diagnostica della pipeline di rendering in Chromium.

Vorremmo condividere alcuni progressi recenti, offrire indicazioni concrete sugli strumenti e discutere delle idee per le future metriche di fluidità delle animazioni. Come sempre, ci piacerebbe per ascoltare il tuo feedback.

Questo post tratterà tre argomenti principali:

  • Una rapida occhiata alle animazioni e ai frame di animazione.
  • Le nostre attuali considerazioni sulla misurazione dello stato generale dell'animazione.
  • Ecco alcuni suggerimenti pratici che oggi puoi sfruttare per gli strumenti di laboratorio.

Cosa sono le animazioni?

Le animazioni danno vita ai contenuti Spostando i contenuti, soprattutto in risposta alle interazioni degli utenti, le animazioni possono rendere l'esperienza più naturale comprensibili e divertenti.

Tuttavia, le animazioni non implementate correttamente o la semplice aggiunta di troppe animazioni possono deteriorano l'esperienza e la rendono decisamente per niente divertente. Probabilmente tutti hanno interagito con un'interfaccia che ha appena aggiunto troppi elementi "utili" transizione che diventano ostili da sperimentare quando hanno un rendimento scarso. Alcuni utenti potrebbero quindi preferisci le immagini ridimensionate, una preferenza dell'utente che dovresti rispettare.

Come funzionano le animazioni?

Per riassumere brevemente, la pipeline di rendering consiste di alcune fasi sequenziali:

  1. Stile:calcola il stili applicabili agli elementi.
  2. Layout: genera il la geometria e la posizione di ogni elemento.
  3. Paint: compila pixel per ogni elemento suddivisi in livelli.
  4. Composito: disegna i livelli allo schermo.

Sebbene esistano molti modi per definire le animazioni, tutti funzionano fondamentalmente uno dei seguenti:

  • Modificare il layout proprietà.
  • Regolare la vernice proprietà.
  • Regolare l'elemento composito proprietà.

Poiché queste fasi sono sequenziali, è importante definire le animazioni in i termini delle proprietà più avanti nella pipeline. Prima dell'aggiornamento maggiore è il costo ed è meno probabile liscia. Consulta la sezione Rendering prestazioni per ulteriori informazioni.)

Sebbene possa essere conveniente animare le proprietà di layout, anche se questi costi non sono immediatamente evidenti. Le animazioni devono essere in termini di modifiche delle proprietà composte, se possibile.

Definizione di animazioni CSS dichiarative o utilizzo Animazioni, e verificando che l'animazione di composizione proprietà, è un ottimo primo passo per garantire animazioni fluide ed efficienti. Tuttavia, questo da solo non garantisce la fluidità, perché anche le animazioni web efficienti hanno limiti di prestazioni. Ecco perché è sempre importante misurare.

Cosa sono i frame dell'animazione?

Gli aggiornamenti alla rappresentazione visiva di una pagina richiedono del tempo. Un elemento visivo porterà a un nuovo frame dell'animazione, che alla fine viene visualizzato display dell'utente.

I display si aggiornano a intervalli regolari, quindi gli aggiornamenti visivi vengono raggruppati. Molti display vengono aggiornate in base a un intervallo di tempo fisso, ad esempio 60 volte al secondo 60 Hz). Alcuni display più moderni possono offrire frequenze di aggiornamento più elevate (90-120 Hz stanno diventando comuni). Spesso questi display sono in grado di adattarsi attivamente frequenza di aggiornamento, se necessario, o persino offrire frequenze fotogrammi completamente variabili.

L'obiettivo di qualsiasi applicazione, come un gioco o un browser, è elaborare tutte queste aggiornamenti visivi in batch e produrre un frame di animazione visivamente completo all'interno la scadenza, sempre. Tieni presente che questo obiettivo è completamente distinto dagli altri importanti attività del browser, come il caricamento rapido dei contenuti dalla rete di eseguire attività JavaScript in modo efficiente.

A un certo punto può diventare troppo difficile completare tutti gli aggiornamenti visivi all'interno la scadenza assegnata assegnata dal display. In questi casi, il browser permette di inserire un frame. Lo schermo non diventa nero, si limita a ripetersi. Vedi lo stesso aggiornamento visivo per un po' più di tempo, lo stesso frame dell'animazione presentati nell'opportunità del frame precedente.

In realtà questo accade spesso. Non è necessariamente nemmeno percettibile, soprattutto per contenuti statici o simili a documenti, che sono comuni sulla piattaforma web in particolare. I frame eliminati diventano evidenti solo quando ci sono elementi visivi importanti Aggiornamenti, come le animazioni, per i quali abbiamo bisogno di un flusso costante di animazione si aggiorna per mostrare un movimento fluido.

Cosa influisce sui fotogrammi dell'animazione?

Gli sviluppatori web possono influire notevolmente sulla capacità di un browser di eseguire il rendering e presentare gli aggiornamenti visivi in modo efficiente.

Ecco alcuni esempi:

  • Utilizzo di contenuti troppo grandi o che richiedono molte risorse per essere decodificati rapidamente dispositivo di destinazione.
  • Ne utilizzo eccessivo strati È richiesta troppa memoria GPU.
  • Definizione di stili CSS o animazioni web eccessivamente complessi.
  • Utilizzo di anti-pattern di progettazione che disattivano le ottimizzazioni del rendering rapido.
  • Troppo lavoro JS sul thread principale, il che genera attività lunghe che bloccano le immagini aggiornamenti.

Ma come fai a sapere quando il frame dell'animazione non ha raggiunto la scadenza e ha causato un fotogramma caduto?

Uno dei possibili metodi consiste nell'utilizzare requestAnimationFrame() sondaggio, tuttavia presenta diversi lati negativi. requestAnimationFrame(), o "rAF", indica al browser che vuoi eseguire un'animazione e richiede un comando di eseguire questa operazione prima della fase successiva di rendering della pipeline di rendering. Se funzione di callback non viene chiamata nel momento previsto, ciò significa La colorazione non è stata eseguita e sono stati saltati uno o più frame. Con i sondaggi e contando la frequenza con cui viene chiamata rAF, puoi calcolare una sorta di "frame al secondo" f/s.

let frameTimes = [];
function pollFramesPerSecond(now) {
  frameTimes = [...frameTimes.filter(t => t > now - 1000), now];
  requestAnimationFrame(pollFramesPerSecond);
  console.log('Frames per second:', frameTimes.length);
}
requestAnimationFrame(pollFramesPerSecond);

L'utilizzo dei sondaggi in requestAnimationFrame() non è una buona idea per diversi motivi:

  • Ogni script deve impostare il proprio loop di polling.
  • Può bloccare il percorso critico.
  • Anche se il polling rAF è veloce, può impedire requestIdleCallback() la possibilità di programmare blocchi di inattività lunghi se utilizzati continuativamente (blocchi che oltre un singolo frame).
  • Analogamente, la mancanza di blocchi di inattività lunghi impedisce al browser di pianificare altri di attività a lunga esecuzione (come garbage collection più lunga e altri background lavoro speculativo).
  • Se il polling è attivato e disattivato, non perderai i casi in cui il budget del frame è stato superato.
  • I sondaggi segnaleranno i falsi positivi nei casi in cui il browser utilizzi frequenza di aggiornamento variabile (ad es. a causa dell'alimentazione o dello stato di visibilità).
  • Ma soprattutto, non consente di acquisire tutti i tipi di animazione aggiornamenti.

Troppo lavoro sul thread principale può influire sulla capacità di visualizzare i frame dell'animazione. Dai un'occhiata a Jank Esempio per scoprire come Animazione basata su rAF, quando il lavoro sul thread principale è eccessivo (come ), determina l'interruzione dei frame e il minor numero di callback rAF, con una riduzione del numero di f/s.

Quando il thread principale si blocca, gli aggiornamenti visivi iniziano a interrompersi. È un peccato!

Molti strumenti di misurazione si sono concentrati in modo particolare sulla capacità dei principali thread per cedere in modo tempestivo e per i frame dell'animazione. Ma non è tutto. Considera l'esempio seguente:

Il video riportato sopra mostra una pagina che inserisce periodicamente attività lunghe nella . Queste lunghe attività rovinano completamente la capacità della pagina di fornire alcuni tipi di aggiornamenti visivi e puoi vedere nell'angolo in alto a sinistra diminuzione corrispondente pari a 0 di requestAnimationFrame() f/s registrati.

Eppure, nonostante queste attività lunghe, la pagina continua a scorrere senza problemi. Questo perché nei browser moderni lo scorrimento è spesso con conversazioni in thread, gestiti interamente dal compositore.

Questo è un esempio che contiene contemporaneamente molti frame eliminati sulla ma ci sono ancora molti frame di scorrimento caricati correttamente del compositore. Una volta completata l'attività lunga, il colore del thread principale viene aggiornato non ha comunque alcuna modifica visiva da offrire. Il polling rAF ha suggerito un calo dei fotogrammi a 0, ma visivamente, l'utente non potrebbe notare alcuna differenza.

Per i fotogrammi delle animazioni, la storia non è così semplice.

Frame di animazione: aggiornamenti importanti

L'esempio sopra mostra che la storia non si limita a requestAnimationFrame().

Quando sono importanti gli aggiornamenti e i fotogrammi dell'animazione? Ecco ci sono alcuni criteri che stiamo valutando e su cui vorremmo ricevere un feedback:

  • Aggiornamenti del thread principale e del compositore
  • Aggiornamenti relativi alla vernice mancanti
  • Rilevamento delle animazioni
  • Qualità e quantità

Aggiornamenti del thread principale e del compositore

Gli aggiornamenti del frame dell'animazione non sono booleani. Non è il caso che i frame possano essere completamente scartati o presentati per intero. Esistono molti motivi per cui un'animazione il frame può essere parzialmente presentato. In altre parole, può avere contemporaneamente con contenuti obsoleti ma anche con nuovi aggiornamenti visivi, presentati.

L'esempio più comune è quando il browser non è in grado di generare un nuovo il thread principale si aggiorna entro la scadenza del frame, ma ha un nuovo thread del compositore (come l'esempio di scorrimento in thread di prima).

Un motivo importante per l'utilizzo di animazioni dichiarative per animare elementi composti proprietà è che in questo modo si può guidare un'animazione interamente dal thread del compositore anche quando il thread principale è occupato. Questi tipi di animazioni possono continuare a produrre aggiornamenti visivi in modo efficiente parallelo.

In altri casi, potrebbero verificarsi casi in cui un aggiornamento del thread principale disponibili per la presentazione, ma solo dopo aver mancato di diverse scadenze. Qui il browser avrà alcuni nuovi aggiornamenti, ma potrebbe non essere il più recente.

In termini generali, prendiamo in considerazione i frame che contengono nuovi aggiornamenti visivi, senza tutti i nuovi aggiornamenti visivi, come un frame parziale. I frame parziali sono abbastanza comuni. Idealmente, gli aggiornamenti parziali dovrebbero includere almeno i dati più importanti aggiornamenti visivi, come le animazioni, ma ciò può avvenire solo se le animazioni sono generato dal thread del compositore.

Aggiornamenti relativi alla vernice mancanti

Un altro tipo di aggiornamento parziale è quando i contenuti multimediali come le immagini non hanno terminato. decodifica e rasterizzazione in tempo per la presentazione in frame.

Oppure, anche se una pagina è perfettamente statica, i browser potrebbero comunque rimanere indietro nel rendering aggiornamenti visivi durante lo scorrimento rapido. Questo perché le versioni in pixel i contenuti al di fuori dell'area visibile possono essere ignorati per risparmiare memoria GPU. it richiede tempo per eseguire il rendering dei pixel e potrebbe richiedere più tempo di un singolo frame eseguire il rendering di tutto dopo un grande rotolo, ad esempio uno scorrimento delle dita. Di solito noto come scacchiera.

Con ogni opportunità di rendering del frame, è possibile tenere traccia di quante gli ultimi aggiornamenti visivi sono arrivati sullo schermo. Misurare la capacità di farlo su molti frame (o tempi) è generalmente nota come velocità effettiva frame.

Se la GPU è davvero bloccata, il browser (o la piattaforma) potrebbe iniziare a limita la frequenza con cui tenta gli aggiornamenti visivi e quindi diminuisce e le frequenze fotogrammi effettive. Tecnicamente ciò può ridurre il numero di aggiornamenti di frame, visivamente verrà comunque visualizzato come una velocità effettiva di frame inferiore.

Tuttavia, non tutti i tipi di velocità effettiva frame bassi sono scadenti. Se la pagina è per lo più inattiva e non ci sono animazioni attive, una bassa frequenza fotogrammi ha una frequenza fotogrammi elevata (e può risparmiare batteria!).

Quando è importante la velocità effettiva del frame?

Rilevamento delle animazioni

La velocità effettiva di frame elevata è importante soprattutto nei periodi con dati le animazioni. I diversi tipi di animazione dipenderanno dagli aggiornamenti visivi thread specifico (principale, compositore o worker), quindi l'aggiornamento visivo dipende dal thread che fornisce il suo aggiornamento entro la scadenza. Diciamo che un determinato thread influisce sulla fluidità ogni volta che è presente un'animazione attiva che dipende dall'aggiornamento del thread.

Alcuni tipi di animazioni sono più facili da definire e rilevare rispetto ad altri. Le animazioni dichiarative, o animazioni basate su input dell'utente, sono più chiare da definire rispetto alle animazioni basate su JavaScript implementate come aggiornamenti periodici agli elementi animabili proprietà degli stili.

Anche con requestAnimationFrame() tu non sempre può presupporre che ogni chiamata rAF produca necessariamente un aggiornamento o un'animazione. Ad esempio, usare il polling rAF solo per tenere traccia della frequenza fotogrammi (come mostrato sopra) non dovrebbe di per sé influire sulle misurazioni della fluidità poiché nessun aggiornamento visivo.

Qualità e quantità

Infine, il rilevamento delle animazioni e degli aggiornamenti dei frame di animazione è ancora solo parte la storia perché acquisisce solo la quantità di aggiornamenti dell'animazione, non qualità.

Ad esempio, potresti vedere una frequenza fotogrammi costante di 60 f/s mentre guardi un video. Tecnicamente, l'audio è perfettamente fluido, ma il video stesso potrebbe avere un bassa velocità in bit o problemi con il buffering di rete. Non viene acquisita da metriche di fluidità dell'animazione, che però potrebbero essere fastidiose utente.

Oppure un gioco che sfrutta <canvas> (magari anche con tecniche quali fuori schermo canvas su assicura una frequenza fotogrammi stabile) può essere tecnicamente perfettamente fluida in termini di frame di animazione, il tutto senza caricare asset di gioco di alta qualità nel scena o l'esposizione di artefatti di rendering.

Ovviamente, un sito può avere solo animazioni di pessima qualità 🙂

GIF vecchia scuola in costruzione

Voglio dire, immagino che fossero abbastanza forti per il loro tempo!

Stati di un singolo frame di animazione

Perché i frame possono essere presentati parzialmente oppure i frame eliminati possono verificarsi in modi diversi che non influiscono sulla fluidità, abbiamo iniziato a pensare a ogni frame come a una il punteggio di completezza o fluidità.

Ecco lo spettro di modi in cui interpretiamo lo stato di un singolo frame dell'animazione, in ordine decrescente:

Nessun aggiornamento richiesto Tempo di inattività, ripeti del frame precedente.
Completamente presentato L'aggiornamento del thread principale è stato eseguito entro la scadenza oppure no era necessario aggiornare il thread principale.
Presenta parzialmente Solo compositore; l'aggiornamento ritardato del thread principale non aveva immagini modifica.
Presenta parzialmente Solo compositore; il thread principale presentava un aggiornamento visivo, non includeva un'animazione che influisce sulla fluidità.
Presenta parzialmente Solo compositore; il thread principale presentava un aggiornamento visivo che influisce morbidezza, ma è stato utilizzato un frame precedentemente inattivo.
Presenta parzialmente Solo compositore; senza l'aggiornamento principale desiderato e L'aggiornamento del compositore include un'animazione che influisce sulla fluidità.
Presenta parzialmente Solo il compositore, ma l'aggiornamento del compositore non ha che influisce sulla fluidità.
Frame interrotto Nessun aggiornamento. Non era richiesto alcun aggiornamento del compositore, ma il principale era in ritardo.
Frame interrotto Volevamo un aggiornamento del compositore, ma è stato ritardato.
Cornice obsoleta Volevamo un aggiornamento, prodotto dal renderer, ma La GPU non era ancora presente prima della scadenza di vsync.

È possibile trasformare questi stati in un po' di punteggio. E magari in un modo a interpretare questo punteggio è considerarlo una probabilità di essere osservabile per l'utente. Un singolo frame ignorato potrebbe non essere molto osservabile, ma una sequenza di molti frame interrotti che interessano la fluidità in una riga lo sono sicuramente.

Riassumendo: metrica Percentuale di frame persi

Sebbene a volte possa essere necessario approfondire lo stato di ogni frame dell'animazione, è utile anche assegnare un breve riepilogo punteggio per un'esperienza.

I frame possono essere presentati parzialmente e persino saltati completamente gli aggiornamenti dei frame potrebbero effettivamente non influire sulla fluidità, ma vogliamo concentrarti meno contando solo i frame e altro ancora sull'estensione a cui il browser non è in grado Fornire aggiornamenti visivamente completi quando contava.

Il modello mentale dovrebbe passare da:

  1. Frame al secondo, per
  2. Rilevare aggiornamenti dell'animazione mancanti e importanti,
  3. Percentuale diminuita in un determinato periodo di tempo.

Ciò che conta è: la proporzione di tempo di attesa aggiornamenti. Riteniamo che ciò corrisponda al modo naturale con cui gli utenti sperimentano la fluidità dei contenuti web nella pratica. Finora, abbiamo utilizzato i seguenti strumenti insieme iniziale di metriche:

  • Percentuale media ignorata:per tutti i frame dell'animazione non inattivi nell'intero periodo. tutta la sequenza temporale
  • Caso peggiore di percentuale di frame persi: misurato su uno scorrimento di 1 secondo finestre temporali.
  • 95° percentile di frame eliminati: misurato in 1 secondo finestre temporali scorrevoli.

Puoi trovare questi punteggi in alcuni strumenti per sviluppatori di Chrome oggi. Anche se questi si concentrano solo sulla velocità effettiva complessiva del frame, valutiamo anche altri come la latenza del frame.

Mettiti alla prova con gli strumenti per sviluppatori.

HUD prestazioni

Chromium ha un pratico HUD per le prestazioni nascosto da una bandiera (chrome://flags/#show-performance-metrics-hud) Qui puoi trovare i diversi per aspetti come Core Web Vitals e anche per alcune definizioni sperimentali per ottenere una fluidità dell'animazione in base alla percentuale di frame persi nel tempo.

HUD prestazioni

Statistiche di rendering del frame

Attiva "Frame di rendering Statistiche" in DevTools tramite le impostazioni di rendering per esaminare in tempo reale nuovi frame di animazione. che sono codificati per colore per distinguere gli aggiornamenti parziali dai frame completamente eliminati aggiornamenti. Il numero f/s riportato è solo per i frame completamente presentati.

Statistiche di rendering del frame

Il visualizzatore frame nelle registrazioni del profilo delle prestazioni di DevTools

Il rendimento di DevTools ha aveva a lungo un frame visualizzatore. Tuttavia, era un po' non sincronizzato con il modo in cui la moderna pipeline di rendering funziona davvero. Di recente ci sono stati molti miglioramenti, anche nell'ultima Chrome Canary, che riteniamo semplifica notevolmente il debug dei problemi di animazione.

Oggi scoprirai che i fotogrammi nel visualizzatore dei frame sono più allineati con Confini vsync e codificati per colore in base allo stato. Non è ancora pieno per tutte le sfumature descritte sopra, ma abbiamo intenzione di aggiungerne altre nel prossimo futuro.

Visualizzatore frame in Chrome DevTools

Tracciamento di Chrome

Infine, con il tracciamento di Chrome, lo strumento preferito per approfondire i dettagli, puoi registrare un "rendering dei contenuti web" traccia con il nuovo Perfetto UI (o about:tracing) e approfondire le funzionalità una pipeline grafica. Può essere un'attività scoraggiante, ma ci sono alcune cose aggiunti di recente a Chromium per semplificare l'operazione. Puoi ottenere una panoramica disponibili in Life of a Cornice documento.

Attraverso gli eventi traccia, puoi determinare in modo definitivo:

  • Quali animazioni sono in esecuzione (utilizzando eventi denominati TrackerValidation).
  • Recupero della sequenza temporale esatta dei frame dell'animazione (utilizzando gli eventi denominati PipelineReporter).
  • Per aggiornamenti di animazione complessi, scopri esattamente cosa blocca l'esecuzione dell'animazione più rapidamente (utilizzando le suddivisioni degli eventi in PipelineReporter eventi).
  • Per le animazioni basate su input, scopri quanto tempo occorre per ricevere un aggiornamento visivo (con eventi denominati EventLatency).

Reporter pipeline di traccia di Chrome

Passaggi successivi

L'iniziativa Web Vitals ha lo scopo di fornire metriche e indicazioni per creare esperienze utente eccezionali sul web. Metriche basate su lab come Totale il blocco del tempo (TBT) è fondamentale per rilevare e diagnosticare potenziali problemi di interattività. Abbiamo in programma di progettare una metrica simile basata su lab per ottenere un'animazione fluida.

Vi aggiorneremo man mano che sviluppiamo nuove idee per la progettazione di una una metrica completa basata sui dati dei singoli frame dell'animazione.

In futuro, vorremmo anche progettare API che permettano di misurare fluidità dell'animazione per gli utenti reali nel field e nel lab. Continua a seguirci per non perderti gli aggiornamenti.

Feedback

Siamo entusiasti di tutti i recenti miglioramenti e degli strumenti per sviluppatori che hanno disponibili in Chrome per misurare la fluidità dell'animazione. Prova questi strumenti, confronta le tue animazioni e facci sapere dove conduce.

Puoi inviare i tuoi commenti all' web-vitals-feedback Google raggruppa con "[Metriche di fluidità]" nella riga dell'oggetto. Stiamo davvero cercando impaziente di conoscere la vostra opinione.