API Long Animation Frames

L'API Long Animation Frames (loAF, pronunciato Lo-Af) è un aggiornamento dell'API Long Tasks che consente di comprendere meglio gli aggiornamenti lenti dell'interfaccia utente (UI). Questo può essere utile per identificare frame di animazione lenti che potrebbero influire sulla metrica Core Web Vital Interaction to Next Paint (INP) che misura l'adattabilità o per identificare altri problemi di UI che influiscono sulla fluidità.

Stato dell'API

Supporto dei browser

  • Chrome: 123.
  • Edge: 123.
  • Firefox: non supportato.
  • Safari: non supportato.

Origine

A seguito di una prova dell'origine da Chrome 116 a Chrome 122, l'API LoAF è stata spedita da Chrome 123.

Informazioni di base: l'API Long Tasks

Supporto dei browser

  • Chrome: 58.
  • Edge: 79.
  • Firefox: non supportato.
  • Safari: non supportato.

Origine

L'API Long Animation Frames è un'alternativa all'API Long Tasks, disponibile in Chrome da un po' di tempo (da Chrome 58). Come suggerisce il nome, l'API Long Task consente di monitorare le attività lunghe, ovvero quelle che occupano il thread principale per almeno 50 millisecondi. È possibile monitorare le attività lunghe utilizzando l'interfaccia di PerformanceLongTaskTiming con un PeformanceObserver:

const observer = new PerformanceObserver((list) => {
  console.log(list.getEntries());
});

observer.observe({ type: 'longtask', buffered: true });

Le attività lunghe potrebbero causare problemi di reattività. Se un utente tenta di interagire con una pagina, ad esempio facendo clic su un pulsante o aprendo un menu, ma il thread principale sta già gestendo un'attività lunga, l'interazione dell'utente viene ritardata in attesa del completamento dell'attività.

Per migliorare la reattività, spesso è consigliato suddividere attività lunghe. Se invece ogni attività lunga viene suddivisa in una serie di attività più piccole, è possibile eseguire attività più importanti tra una e l'altra per evitare ritardi significativi nella risposta alle interazioni.

Pertanto, quando si cerca di migliorare la reattività, il primo passaggio è spesso eseguire una traccia delle prestazioni e esaminare le attività lunghe. Ad esempio, puoi utilizzare uno strumento di controllo basato su lab come Lighthouse (che include un controllo Evita attività lunghe nel thread principale) o esaminare le attività lunghe in Chrome DevTools.

I test in laboratorio spesso non sono un buon punto di partenza per identificare i problemi di reattività, in quanto questi strumenti potrebbero non includere le interazioni, o se lo fanno, si tratta di un piccolo sottoinsieme di interazioni probabili. L'ideale sarebbe misurare le cause delle interazioni lente sul campo.

Mancanza di API Long Tasks

La misurazione di attività lunghe sul campo utilizzando un osservatore del rendimento è utile solo in parte. In realtà, non fornisce così tante informazioni, a parte il fatto che si sia verificata un'attività lunga e il tempo che ci è voluto.

Gli strumenti di Real User Monitoring (RUM) spesso lo usano per tracciare il numero o la durata delle attività lunghe o per identificare le pagine su cui si verificano. Tuttavia, senza i dettagli sottostanti su cosa ha causato l'attività lunga, questa funzionalità è di uso limitato. L'API Long Tasks ha solo un modello di attribuzione di base, che al massimo indica solo il contenitore in cui si è verificata l'attività lunga (il documento di primo livello o un <iframe>), ma non lo script o la funzione che lo ha chiamato, come mostrato da una voce tipica:

{
  "name": "unknown",
  "entryType": "longtask",
  "startTime": 31.799999997019768,
  "duration": 136,
  "attribution": [
    {
      "name": "unknown",
      "entryType": "taskattribution",
      "startTime": 0,
      "duration": 0,
      "containerType": "window",
      "containerSrc": "",
      "containerId": "",
      "containerName": ""
    }
  ]
}

Anche l'API Long Tasks è una visualizzazione incompleta, poiché può escludere anche alcune attività importanti. Alcuni aggiornamenti, come il rendering, avvengono in attività separate che idealmente dovrebbero essere incluse insieme all'esecuzione precedente che ha causato l'aggiornamento per misurare con precisione il "lavoro totale" per quell'interazione. Per ulteriori dettagli sulle limitazioni dell'utilizzo delle attività, consulta la sezione "Limiti delle attività lunghe" della spiegazione.

Il problema finale è che la misurazione delle attività lunghe genera report solo sulle singole attività che richiedono più tempo del limite di 50 millisecondi. Un frame di animazione può essere costituito da diverse attività di dimensioni inferiori a questo limite di 50 millisecondi, pur continuando a bloccare la capacità del browser di eseguire il rendering.

L'API Long Animation Frames

Supporto dei browser

  • Chrome: 123.
  • Edge: 123.
  • Firefox: non supportato.
  • Safari: non supportato.

Origine

La Long Animation Frames API (LoAF) è una nuova API che cerca di risolvere alcuni dei problemi dell'API Long Tasks per consentire agli sviluppatori di ottenere informazioni più strategiche per risolvere i problemi di reattività e migliorare INP, oltre a ottenere informazioni sui problemi di fluidità.

Una buona adattabilità significa che una pagina risponde rapidamente alle interazioni che vengono effettuate con essa. Ciò comporta la possibilità di visualizzare in modo tempestivo tutti gli aggiornamenti necessari per l'utente ed evitare di bloccarne l'esecuzione. Per l'INP, è consigliabile rispondere in massimo 200 millisecondi, ma per altri aggiornamenti (ad esempio le animazioni) anche 200 millisecondi potrebbero essere troppo.

L'API Long Animation Frames è un approccio alternativo per misurare il lavoro di blocco. Anziché misurare le singole attività, l'API Long Animation Frames, come suggerisce il nome, misura i frame dell'animazione lunghi. Un frame di animazione lungo si verifica quando un aggiornamento del rendering è in ritardo oltre i 50 millisecondi (la stessa soglia per l'API Long Tasks).

I frame di animazione lunghi vengono misurati dall'inizio delle attività che richiedono un rendering. Se la prima attività in un potenziale frame dell'animazione lungo non richiede un rendering, il frame dell'animazione lungo viene terminato al termine dell'attività senza rendering e viene avviato un nuovo potenziale frame dell'animazione lungo con l'attività successiva. Questi frame di animazione lunghi che non vengono visualizzati sono comunque inclusi nell'API Long Animation Frames se sono superiori a 50 millisecondi (con un tempo renderStart pari a 0) per consentire la misurazione del lavoro potenzialmente bloccante.

È possibile osservare lunghi frame dell'animazione in modo simile alle attività lunghe con un PerformanceObserver, ma esaminando il tipo long-animation-frame:

const observer = new PerformanceObserver((list) => {
  console.log(list.getEntries());
});

observer.observe({ type: 'long-animation-frame', buffered: true });

È anche possibile eseguire query sui frame di animazione lunghi precedenti dalla Cronologia del rendimento nel seguente modo:

const loafs = performance.getEntriesByType('long-animation-frame');

Tuttavia, esiste un maxBufferSize per le voci sul rendimento dopo le quali le voci più recenti vengono eliminate, pertanto l'approccio PerformanceObserver è quello consigliato. La dimensione del buffer long-animation-frame è impostata su 200, come per long-tasks.

Vantaggi di esaminare i frame invece delle attività

Il vantaggio principale di esaminare il problema dal punto di vista dei frame anziché delle attività è che un'animazione lunga può essere composta da un numero qualsiasi di attività che, sommate, hanno generato un frame di animazione lungo. Questo risolve il punto finale menzionato in precedenza, in cui la somma di molte attività più piccole che bloccano il rendering prima di un frame di animazione potrebbe non essere visualizzata dall'API Long Tasks.

Un ulteriore vantaggio di questa visualizzazione alternativa per le attività lunghe è la possibilità di fornire suddivisioni dei tempi dell'intero frame. Anziché includere solo un startTime e un duration, come l'API Long Tasks, LoAF include una suddivisione molto più dettagliata delle varie parti della durata del frame.

Timestamp e durate dei frame

  • startTime: l'ora di inizio del frame dell'animazione lungo rispetto all'ora di inizio della navigazione.
  • duration: la durata del lungo frame dell'animazione (escluso il tempo di presentazione).
  • renderStart: l'ora di inizio del ciclo di rendering, che include i callback requestAnimationFrame, il calcolo di stile e layout, i callback dell'osservatore di ridimensionamento e dell'osservatore di intersezione.
  • styleAndLayoutStart: l'inizio del periodo di tempo impiegato per i calcoli di stile e layout.
  • firstUIEventTimestamp: il momento del primo evento dell'interfaccia utente (mouse/tastiera e così via) da gestire durante il corso di questo frame.
  • blockingDuration: la durata totale in millisecondi durante la quale il frame dell'animazione bloccherà l'elaborazione dell'input o di altre attività ad alta priorità.

Una spiegazione di blockingDuration

Un frame di animazione lungo può essere composto da una serie di attività. Il blockingDuration è la somma delle durate delle attività superiori a 50 millisecondi (inclusa la durata del rendering finale all'interno dell'attività più lunga).

Ad esempio, se un frame di animazione lungo è composto da due attività di 55 millisecondi e 65 millisecondi seguite da un rendering di 20 millisecondi, duration sarà di circa 140 millisecondi con un blockingDuration di (55 - 50) + (65 + 20 - 50) = 40 millisecondi. Per 40 millisecondi durante questo frame di animazione lungo 140 millisecondi, il frame è stato considerato bloccato per la gestione dell'input.

Se guardare duration o blockingDuration

Per la normale visualizzazione a 60 hertz, un browser tenterà di pianificare un frame almeno ogni 16,66 millisecondi (per garantire aggiornamenti fluidi) o dopo un'attività ad alta priorità come la gestione degli input (per garantire aggiornamenti reattivi). Tuttavia, se non ci sono input né altre attività ad alta priorità, ma è presente una coda di altre attività, in genere il browser continuerà il frame corrente ben oltre 16,66 millisecondi, indipendentemente da quanto siano suddivise le attività al suo interno. In altre parole, il browser cercherà sempre di dare la priorità agli input, ma potrebbe scegliere di gestire una coda di attività anziché gli aggiornamenti di rendering. Questo è dovuto al fatto che il rendering è un processo costoso, quindi l'elaborazione di un'attività di rendering combinata per più attività in genere comporta una riduzione complessiva del lavoro.

Pertanto, i frame di animazione lunghi con un valore blockingDuration basso o nullo dovrebbero comunque essere sensibili all'input. Ridurre o eliminare blockingDuration suddividendo attività lunghe è quindi fondamentale per migliorare la reattività misurata da INP.

Tuttavia, molti frame di animazione lunghi, indipendentemente da blockingDuration, indicano aggiornamenti dell'interfaccia utente in ritardo e possono comunque influire sulla fluidità e dare la sensazione di un'interfaccia utente lenta per lo scorrimento o le animazioni, anche se questi problemi sono meno gravi per la reattività misurata dall'INP. Per comprendere i problemi in questo ambito, consulta il duration, ma l'ottimizzazione può essere più complessa in quanto non puoi risolvere il problema suddividendo il lavoro, ma devi ridurre il lavoro.

Tempi fotogrammi

I timestamp menzionati in precedenza consentono di suddividere il lungo frame dell'animazione in tempistiche:

Tempi Calcolo
Ora di inizio startTime
Ora di fine startTime + duration
Durata del lavoro renderStart ? renderStart - startTime : duration
Durata rendering renderStart ? (startTime + duration) - renderStart: 0
Rendering: durata pre-layout styleAndLayoutStart ? styleAndLayoutStart - renderStart : 0
Rendering: durata di stile e layout styleAndLayoutStart ? (startTime + duration) - styleAndLayoutStart : 0

Migliore attribuzione script

Il tipo di voce long-animation-frame include dati di attribuzione migliori di ogni script che ha contribuito a un frame di animazione lungo (per script più lunghi di 5 millisecondi).

Analogamente all'API Long Tasks, verrà fornita in un array di voci di attribuzione, ciascuna delle quali fornisce i seguenti dettagli:

  • Sia name che EntryType restituiranno script.
  • Un invoker significativo che indica come è stato chiamato lo script (ad esempio 'IMG#id.onload', 'Window.requestAnimationFrame' o 'Response.json.then').
  • invokerType del punto di ingresso dello script:
    • user-callback: un callback noto registrato dall'API di una piattaforma web (ad esempio setTimeout, requestAnimationFrame).
    • event-listener: un ascoltatore di un evento della piattaforma (ad es. click, load, keyup).
    • resolve-promise: gestore di una promessa della piattaforma (ad esempio fetch(). Tieni presente che, nel caso delle promesse, tutti i gestori delle stesse promesse vengono combinati in un unico "script"..
    • reject-promise: come per resolve-promise, ma per il rifiuto.
    • classic-script: valutazione dello script (ad es. <script> o import())
    • module-script: come classic-script, ma per gli script dei moduli.
  • Separa i dati temporali per lo script:
    • startTime: ora in cui è stata richiamata la funzione di inserimento.
    • duration: la durata tra il giorno startTime e il momento in cui la coda di microattività successiva ha terminato l'elaborazione.
    • executionStart: l'ora dopo la compilazione.
    • forcedStyleAndLayoutDuration: il tempo totale impiegato per l'elaborazione del layout e dello stile forzati all'interno di questa funzione (vedi thrashing).
    • pauseDuration: tempo totale trascorso in "mettere in pausa" le operazioni sincrone (avviso, XHR sincrona).
  • Dettagli sull'origine dello script:
    • sourceURL: il nome della risorsa dello script, se disponibile (o vuoto se non trovata).
    • sourceFunctionName: il nome della funzione dello script, dove disponibile (o vuoto se non trovato).
    • sourceCharPosition: la posizione del carattere dello script, se disponibile (o -1 se non trovato).
  • windowAttribution: il contenitore (il documento di primo livello o <iframe>) in cui si è verificato il lungo frame dell'animazione.
  • window: un riferimento alla finestra della stessa origine.

Se fornite, le voci di origine consentono agli sviluppatori di sapere esattamente come è stato chiamato ogni script nel frame dell'animazione lunga, fino alla posizione del carattere nello script di chiamata. In questo modo viene indicata la posizione esatta in una risorsa JavaScript che ha generato il frame di animazione lungo.

Esempio di voce sul rendimento long-animation-frame

Un esempio completo di voce relativa al rendimento di long-animation-frame, contenente un singolo script, è:

{
  "blockingDuration": 0,
  "duration": 60,
  "entryType": "long-animation-frame",
  "firstUIEventTimestamp": 11801.099999999627,
  "name": "long-animation-frame",
  "renderStart": 11858.800000000745,
  "scripts": [
    {
      "duration": 45,
      "entryType": "script",
      "executionStart": 11803.199999999255,
      "forcedStyleAndLayoutDuration": 0,
      "invoker": "DOMWindow.onclick",
      "invokerType": "event-listener",
      "name": "script",
      "pauseDuration": 0,
      "sourceURL": "https://web.dev/js/index-ffde4443.js",
      "sourceFunctionName": "myClickHandler",
      "sourceCharPosition": 17796,
      "startTime": 11803.199999999255,
      "window": [Window object],
      "windowAttribution": "self"
    }
  ],
  "startTime": 11802.400000000373,
  "styleAndLayoutStart": 11858.800000000745
}

Come puoi vedere, questo fornisce una quantità senza precedenti di dati per consentire ai siti web di comprendere la causa degli aggiornamenti del rendering in ritardo.

Utilizzare l'API Long Animation Frames sul campo

Strumenti come Chrome DevTools e Lighthouse, sebbene utili per rilevare e riprodurre i problemi, sono strumenti di laboratorio che potrebbero non rilevare aspetti importanti dell'esperienza utente che solo i dati sul campo possono fornire.

L'API Long Animation Frames è progettata per essere utilizzata sul campo per raccogliere dati contestuali importanti per le interazioni utente che l'API Long Tasks non poteva. Questo può aiutarti a identificare e riprodurre i problemi di interattività che altrimenti non avresti rilevato.

Supporto dell'API di rilevamento di frame di animazione lunghi

Puoi utilizzare il seguente codice per verificare se l'API è supportata:

if (PerformanceObserver.supportedEntryTypes.includes('long-animation-frame')) {
  // Monitor LoAFs
}

Il caso d'uso più evidente per l'API Long Animation Frames è aiutare a diagnosticare e risolvere i problemi di Interaction to Next Paint (INP) e questo è stato uno dei motivi principali per cui il team di Chrome ha sviluppato questa API. Un INP buono è il caso in cui tutte le interazioni ricevono una risposta in 200 millisecondi o meno dall'interazione fino al completamento del disegno e, poiché l'API Long Animation Frames misura tutti i frame che richiedono 50 ms o più, la maggior parte degli INP problematici dovrebbe includere i dati LoAF per aiutarti a diagnosticare queste interazioni.

"LoAF INP" è il LoAF che include l'interazione INP, come mostrato nel seguente diagramma:

Esempi di frame di animazione lunghi in una pagina, con l&#39;elemento INP LoAF evidenziato.
Una pagina può avere molti LoAF, uno dei quali è correlato all'interazione INP.

In alcuni casi è possibile che un evento INP interessi due LoAF, di solito se l'interazione avviene dopo che il frame ha avviato la parte di rendering del frame precedente, quindi il gestore di eventi viene elaborato nel frame successivo:

Esempi di frame di animazione lunghi in una pagina, con l&#39;elemento INP LoAF evidenziato.
Una pagina può avere molti LoAF, uno dei quali è correlato all'interazione INP.

In alcuni rari casi, è persino possibile che includa più di due LoAF.

La registrazione dei dati dei LoAF associati all'interazione INP ti consente di avere molte più informazioni sull'interazione INP per facilitarne la diagnosi. Ciò è particolarmente utile per comprendere il ritardo dell'input, in quanto puoi vedere quali altri script erano in esecuzione in quel frame.

Può essere utile anche comprendere la durata dell'elaborazione e il ritardo di visualizzazione inspiegabili se i gestori degli eventi non riproducono i valori rilevati per questi, poiché potrebbero essere in esecuzione altri script per gli utenti che potrebbero non essere inclusi nei tuoi test.

Non esiste un'API diretta per collegare una voce INP alla relativa voce o alle relative voci LoAF, anche se è possibile farlo nel codice confrontando le ore di inizio e di fine di ciascuna (vedi lo script di esempio WhyNp). La libreria web-vitals include tutti i LoAF intersecati nella proprietà longAnimationFramesEntries dell'interfaccia di attribuzione INP della versione 4.

Dopo aver collegato la voce o le voci LoAF, puoi includere le informazioni con l'attribuzione INP. L'oggetto scripts contiene alcune delle informazioni più importanti, in quanto può mostrare che cosa altro era in esecuzione in questi frame, quindi inviando nuovamente questi dati al tuo servizio di analisi potrai capire meglio il motivo della lentezza delle interazioni.

Segnalare LoAF per l'interazione INP è un buon modo per trovare i problemi di interattività più urgenti nella tua pagina. Ogni utente può interagire in modo diverso con la tua pagina e, con un volume sufficiente di dati di attribuzione INP, verranno inclusi una serie di potenziali problemi. In questo modo puoi ordinare gli script in base al volume per vedere quali sono correlati a un INP lento.

Segnalare più dati di animazione lunghi a un endpoint di analisi

Uno svantaggio dell'analisi solo dei LoAF INP è che potresti perdere altre potenziali aree di miglioramento che potrebbero causare problemi INP futuri. Ciò può portare a una sensazione di inutilità, in cui risolvi un problema di INP aspettandoti un miglioramento enorme, solo per scoprire che l'interazione più lenta successiva è solo leggermente migliore, quindi il tuo INP non migliora molto.

Pertanto, anziché esaminare solo il tempo di attività senza interazione INP, ti consigliamo di prendere in considerazione tutti i tempi di attività senza interazione durante la vita utile della pagina:

Una pagina con molti LoAF, alcuni dei quali si verificano durante le interazioni anche se non durante l&#39;interazione INP.
Esaminare tutte le LoAF può aiutarti a identificare futuri problemi INP.

Tuttavia, ogni voce LoAF contiene dati considerevoli, pertanto ti consigliamo di limitare l'analisi solo ad alcuni LoAF. Inoltre, poiché le voci dei frame di animazione lunghi possono essere piuttosto grandi, gli sviluppatori devono decidere quali dati della voce devono essere inviati ad Analytics. Ad esempio, i tempi di riepilogo della voce e forse i nomi degli script o un altro insieme minimo di altri dati contestuali che potrebbero essere ritenuti necessari.

Ecco alcuni pattern suggeriti per ridurre la quantità di dati lunghi per i frame dell'animazione:

Il pattern più adatto a te dipende dal punto in cui ti trovi nel tuo percorso di ottimizzazione e dalla frequenza con cui si verificano frame di animazione lunghi. Per un sito che non è mai stato ottimizzato per la reattività prima d'ora, potresti voler limitare solo i LoAF con interazioni, impostare una soglia alta o considerare solo i LoAF più peggiori.

Una volta risolti i problemi comuni di reattività, puoi estendere questo aspetto non limitandoti alle sole interazioni o a durate di blocco elevate oppure abbassando le soglie.

Osservare i frame di animazione lunghi con le interazioni

Per ottenere informazioni oltre il frame di animazione lungo INP, puoi esaminare tutti i LoAF con interazioni (che possono essere rilevate dalla presenza di un valore firstUIEventTimestamp) con un blockingDuration elevato.

Questo può anche essere un metodo più semplice per monitorare le LoAF INP piuttosto che cercare di correlare i due, il che può essere più complesso. Nella maggior parte dei casi, includerà la LoAF INP per una determinata visita e, nei rari casi in cui non lo fa, vengono comunque visualizzate interazioni lunghe che è importante correggere, in quanto potrebbero essere l'interazione INP per altri utenti.

Il seguente codice registra tutte le voci LoAF con un valore blockingDuration superiore a 100 millisecondi in cui si è verificata un'interazione durante il frame. Il valore 100 è stato scelto perché è inferiore alla soglia INP "buona" di 200 millisecondi. Puoi scegliere un valore superiore o inferiore in base alle tue esigenze.

const REPORTING_THRESHOLD_MS = 100;

const observer = new PerformanceObserver(list => {
  for (const entry of list.getEntries()) {
    if (entry.blockingDuration > REPORTING_THRESHOLD_MS &&
      entry.firstUIEventTimestamp > 0
    ) {
      // Example here logs to console, but could also report back to analytics
      console.log(entry);
    }
  }
});
observer.observe({ type: 'long-animation-frame', buffered: true });

Osserva frame di animazione lunghi con durate di blocco elevate

Come miglioramento dell'esame di tutti i fotogrammi di animazione lunghi con interazioni, ti consigliamo di esaminare tutti i fotogrammi di animazione lunghi con durate di blocco elevate. Questi indicano potenziali problemi di INP se un utente interagisce durante questi frame di animazione lunghi.

Il seguente codice registra tutte le voci LoAF con una durata di blocco superiore a 100 millisecondi in cui si è verificata un'interazione durante il frame. Il valore 100 viene scelto qui perché è inferiore alla soglia INP "buon" di 200 millisecondi per identificare potenziali frame problematici, mantenendo al minimo la quantità di frame di animazione lunghi. Puoi scegliere un valore superiore o inferiore in base alle tue esigenze.

const REPORTING_THRESHOLD_MS = 100;

const observer = new PerformanceObserver(list => {
  for (const entry of list.getEntries()) {
    if (entry.blockingDuration > REPORTING_THRESHOLD_MS) {
      // Example here logs to console, but could also report back to analytics
      console.log(entry);
    }
  }
});
observer.observe({ type: 'long-animation-frame', buffered: true });

Osserva frame di animazione lunghi durante gli aggiornamenti critici dell'interfaccia utente per migliorare la fluidità

Come accennato in precedenza, esaminare i frame di animazione lunghi con una durata di blocco elevata può contribuire a risolvere i problemi di reattività degli input. Tuttavia, per una maggiore fluidità, devi esaminare tutti i frame dell'animazione lunghi con un duration lungo.

Poiché questo può generare dati piuttosto inaffidabili, ti consigliamo di limitare le misurazioni a punti chiave con un pattern come questo:

const REPORTING_THRESHOLD_MS = 100;

const observer = new PerformanceObserver(list => {
  if (measureImportantUIupdate) {
    for (const entry of list.getEntries()) {
      if (entry.duration > REPORTING_THRESHOLD_MS) {
        // Example here logs to console, but could also report back to analytics
        console.log(entry);
      }
    }
  }
});
observer.observe({ type: 'long-animation-frame', buffered: true });

async function doUIUpdatesWithMeasurements() {
  measureImportantUIupdate = true;
  await doUIUpdates();
  measureImportantUIupdate = false;
}

Osserva i frame dell'animazione lunghi peggiori

Anziché avere una soglia impostata, i siti potrebbero voler raccogliere i dati sul fotogramma (o sui fotogrammi) dell'animazione più lungo per ridurre il volume di dati che devono essere inviati tramite beacon. Pertanto, indipendentemente dal numero di frame di animazione lunghi di una pagina, vengono inviati solo i dati relativi ai frame peggiori, a cinque, dieci o a qualsiasi numero di frame di animazione lunghi assolutamente necessari.

MAX_LOAFS_TO_CONSIDER = 10;
let longestBlockingLoAFs = [];

const observer = new PerformanceObserver(list => {
  longestBlockingLoAFs = longestBlockingLoAFs.concat(list.getEntries()).sort(
    (a, b) => b.blockingDuration - a.blockingDuration
  ).slice(0, MAX_LOAFS_TO_CONSIDER);
});
observer.observe({ type: 'long-animation-frame', buffered: true });

Queste strategie possono anche essere combinate: esamina solo i 10 LoAF peggiori con interazioni superiori a 100 millisecondi.

Al momento opportuno (idealmente in occasione dell'evento visibilitychange), torna ad Analytics. Per i test locali, puoi utilizzare console.table periodicamente:

console.table(longestBlockingLoAFs);

Identificare pattern comuni in frame di animazione lunghi

Una strategia alternativa consiste nell'esaminare gli script comuni che compaiono più spesso nelle voci dei frame di animazione lunghi. I dati potrebbero essere registrati a livello di script e posizione del personaggio per identificare i trasgressori recidivi.

Questo approccio potrebbe funzionare particolarmente bene per le piattaforme personalizzabili, dove su vari siti è possibile identificare temi o plug-in che causano problemi di prestazioni.

Il tempo di esecuzione degli script comuni o delle origini di terze parti nei frame di animazione lunghi potrebbe essere sommato e riportato per identificare i contributori comuni ai frame di animazione lunghi in un sito o in una raccolta di siti. Ad esempio, per esaminare gli URL:

const observer = new PerformanceObserver(list => {
  const allScripts = list.getEntries().flatMap(entry => entry.scripts);
  const scriptSource = [...new Set(allScripts.map(script => script.sourceURL))];
  const scriptsBySource= scriptSource.map(sourceURL => ([sourceURL,
      allScripts.filter(script => script.sourceURL === sourceURL)
  ]));
  const processedScripts = scriptsBySource.map(([sourceURL, scripts]) => ({
    sourceURL,
    count: scripts.length,
    totalDuration: scripts.reduce((subtotal, script) => subtotal + script.duration, 0)
  }));
  processedScripts.sort((a, b) => b.totalDuration - a.totalDuration);
  // Example here logs to console, but could also report back to analytics
  console.table(processedScripts);
});

observer.observe({type: 'long-animation-frame', buffered: true});

Un esempio di questo output è:

(index) sourceURL count totalDuration
0 'https://example.consent.com/consent.js' 1 840
1 'https://example.com/js/analytics.js' 7 628
2 'https://example.chatapp.com/web-chat.js' 1 5

Utilizzare l'API Long Animation Frames negli strumenti

L'API consente inoltre ulteriori strumenti per gli sviluppatori per il debug locale. Sebbene alcuni strumenti come Lighthouse e Chrome DevTools siano stati in grado di raccogliere gran parte di questi dati utilizzando dettagli di monitoraggio di livello inferiore, l'esistenza di questa API di livello superiore potrebbe consentire ad altri strumenti di accedere a questi dati.

Mostrare i dati dei frame dell'animazione lunghi in DevTools

Puoi visualizzare frame di animazione lunghi in DevTools utilizzando l'API performance.measure(), che vengono poi visualizzati nel canale Tempi utente di DevTools nelle tracce relative alle prestazioni per mostrare dove concentrare gli sforzi per i miglioramenti delle prestazioni. Utilizzando l'API DevTools Extensibility, questi elementi possono anche essere visualizzati nel proprio percorso:

const observer = new PerformanceObserver((list) => {
  for (const entry of list.getEntries()) {
    performance.measure('LoAF', {
      start: entry.startTime,
      end: entry.startTime + entry.duration,
      detail: {
        devtools: {
          dataType: "track-entry",
          track: "Long animation frames",
          trackGroup: "Performance Timeline",
          color: "tertiary-dark",
          tooltipText: 'LoAF'
        }
      }
    });
  }
});

observer.observe({ type: 'long-animation-frame', buffered: true });
Traccia del riquadro Rendimento di DevTools con una traccia personalizzata che mostra i dati relativi ai fotogrammi di animazione lunghi, che possono essere confrontati con il grafico a forma di fiamma principale.
Visualizzazione di dati lunghi relativi ai frame dell'animazione in DevTools.

È probabile che i frame di animazione lunghi e a lungo termine vengano incorporati in DevTools stesso, ma nel frattempo lo snippet di codice precedente consente di visualizzarli.

La prima voce nella figura precedente mostra anche dove il browser ha elaborato più attività contemporaneamente nello stesso frame di animazione lungo anziché eseguire il rendering tra di loro. Come accennato in precedenza, questo può accadere quando non sono presenti attività di input ad alta priorità, ma è presente una coda di attività. Per la prima attività lunga sono necessari alcuni aggiornamenti del rendering da completare (altrimenti il frame dell'animazione lunga corrente verrebbe reimpostato dopo, e uno nuovo inizierà con l'attività successiva), ma invece di eseguire immediatamente il rendering, il browser ha elaborato una serie di attività aggiuntive e solo allora ha eseguito l'attività di rendering lunga e terminato il lungo frame dell'animazione. Questo dimostra l'utilità di esaminare frame di animazione lunghi in DevTools, anziché solo attività lunghe, per identificare il rendering in ritardo.

Utilizzare i dati dei fotogrammi di animazione lunghi in altri strumenti per sviluppatori

L'estensione Web Vitals ha mostrato il valore nelle informazioni di debug del riepilogo del logging per diagnosticare i problemi di prestazioni.

Ora vengono visualizzati anche i dati dei frame di animazione lunghi per ogni callback INP e ogni interazione:

Log della console dell&#39;estensione Web Vitals.
La console di registrazione dell'estensione Web Vitals mostra i dati LoAF.

Utilizza i dati dei frame di animazione lunghi negli strumenti di test automatici

Analogamente, gli strumenti di test automatizzati nelle pipeline CI/CD possono mostrare dettagli su potenziali problemi di prestazioni misurando fotogrammi di animazione lunghi durante l'esecuzione di varie suite di test.

Domande frequenti

Ecco alcune delle domande frequenti su questa API:

Perché non estendere o eseguire l'iterazione dell'API Long Tasks?

Si tratta di un approccio alternativo per generare un report con una misurazione simile, ma in definitiva diversa, dei potenziali problemi di adattabilità. È importante assicurarsi che i siti che si basano sull'API Long Tasks esistente continuino a funzionare per evitare di interrompere i casi d'uso esistenti.

Anche se l'API Long Tasks può trarre vantaggio da alcune delle funzionalità di LoAF (ad esempio un modello di attribuzione migliore), riteniamo che concentrarsi sui frame anziché sulle attività offra molti vantaggi che rendono questa API sostanzialmente diversa rispetto all'API Long Tasks esistente.

Perché non ci sono voci di script?

Ciò potrebbe indicare che il frame di animazione lungo non è dovuto a JavaScript, ma a un'elaborazione di rendering di grandi dimensioni.

Questo può accadere anche quando il frame di animazione lungo è dovuto a JavaScript, ma l'attribuzione dello script non può essere fornita per diversi motivi di privacy, come indicato in precedenza (principalmente perché JavaScript non è di proprietà della pagina).

Perché sono presenti voci di script ma non informazioni o informazioni di origine limitate?

Ciò può accadere per una serie di motivi, tra cui il fatto che non esiste una fonte attendibile a cui fare riferimento.

Le informazioni sugli script saranno limitate anche per gli script no-cors cross-origin, anche se questo problema può essere risolto recuperando gli script utilizzando CORS aggiungendo crossOrigin = "anonymous" alla chiamata <script>.

Ad esempio, lo script Google Tag Manager predefinito da aggiungere alla pagina:

<!-- Google Tag Manager -->
<script>(function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start':
new Date().getTime(),event:'gtm.js'});var f=d.getElementsByTagName(s)[0],
j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src=
'https://www.googletagmanager.com/gtm.js?id='+i+dl;f.parentNode.insertBefore(j,f);
})(window,document,'script','dataLayer','GTM-XXXXXXX');</script>
<!-- End Google Tag Manager -->

Può essere migliorato aggiungendo j.crossOrigin = "anonymous" per consentire di fornire dettagli completi sull'attribuzione per GTM

Sostituirà l'API Long Tasks?

Sebbene riteniamo che l'API Long Animation Frames sia un'API migliore e più completa per la misurazione delle attività lunghe, al momento non è prevista la ritiro dell'API Long Tasks.

Feedback richiesto

I feedback possono essere inviati all'elenco dei problemi di GitHub oppure i bug nell'implementazione dell'API in Chrome possono essere segnalati nel tracker dei problemi di Chrome.

Conclusione

L'API Long Animation Frames è una nuova ed entusiasmante API che offre molti potenziali vantaggi rispetto alla precedente API Long Tasks.

Si sta rivelando uno strumento fondamentale per affrontare i problemi di reattività misurati da INP. INP è una metrica difficile da ottimizzare e questa API è uno dei modi in cui il team di Chrome cerca di semplificare l'identificazione e la risoluzione dei problemi per gli sviluppatori.

L'ambito dell'API Long Animation Frames va oltre l'INP e può aiutare a identificare altre cause di aggiornamenti lenti che possono influire sulla fluidità complessiva dell'esperienza utente di un sito web.

Ringraziamenti

Immagine in miniatura di Henry Be su Unsplash.