L'API Long Animation Frames (LoAF, pronunciato Lo-Af) è un aggiornamento dell'API Long Tasks per 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
A seguito di una prova dell'origine da Chrome 116 a Chrome 122, l'API LoAF è stata implementata a partire da Chrome 123.
Informazioni di base: l'API Long Tasks
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. Le attività lunghe possono essere monitorate utilizzando l'interfaccia 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 è consigliabile suddividere le 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à, poiché 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 molte informazioni oltre al fatto che si è verificata un'attività lunga e al tempo impiegato.
Gli strumenti di monitoraggio dei dati utente reali (RUM) spesso li utilizzano per analizzare la tendenza del numero o della durata delle attività lunghe o per identificare le pagine in cui si verificano, ma senza i dettagli sottostanti che hanno causato l'attività lunga, questo è di scarsa utilità. 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": ""
}
]
}
L'API Long Tasks è anche una visualizzazione incompleta, poiché potrebbe 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 potrebbe essere costituito da diverse attività più piccole di questo limite di 50 millisecondi, ma bloccare collettivamente la capacità di rendering del browser.
L'API Long Animation Frames
L'API Long Animation Frames (LoAF) è una nuova API che cerca di risolvere alcune delle carenze dell'API Long Tasks per consentire agli sviluppatori di ottenere informazioni più utili per risolvere i problemi di reattività e migliorare l'INP, nonché per ottenere informazioni sui problemi di fluidità.
Una buona adattabilità significa che una pagina risponde rapidamente alle interazioni che vengono effettuate con essa. Ciò implica la possibilità di applicare tempestivamente gli aggiornamenti necessari all'utente ed evitare di bloccarli. 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.
I frame di animazione lunghi possono essere osservati in modo simile alle attività lunghe con un PerformanceObserver
, ma guardando 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 relative al 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 dell'analisi dei frame anziché 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 frame dell'animazione lunga (escluso il tempo di presentazione).renderStart
: l'ora di inizio del ciclo di rendering, che include i callbackrequestAnimationFrame
, 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 per cui 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à. blockingDuration
è la somma delle durate delle attività superiori a 50 millisecondi (inclusa la durata del rendering finale nell'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 le attività lunghe è quindi fondamentale per migliorare la reattività misurata dall'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 questa area, consulta duration
, ma questi possono essere più difficili da ottimizzare perché non puoi risolverli suddividendo il lavoro, ma devi ridurlo.
Tempi dei frame
I timestamp sopra menzionati consentono di suddividere il frame dell'animazione lunga in tempi:
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 del 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).
Come per l'API Long Tasks, verrà fornito in un array di voci di attribuzione, ognuna delle quali contiene i seguenti dettagli:
- Sia
name
cheEntryType
restituirannoscript
. - Un
invoker
significativo che indica come è stato chiamato lo script (ad esempio'IMG#id.onload'
,'Window.requestAnimationFrame'
o'Response.json.then'
). - Il
invokerType
del punto di accesso dello script:user-callback
: un callback noto registrato da un'API di piattaforma web (ad esempiosetTimeout
,requestAnimationFrame
).event-listener
: un ascoltatore di un evento della piattaforma (ad es.click
,load
,keyup
).resolve-promise
: gestore di una promessa della piattaforma (ad esempiofetch()
. Tieni presente che, nel caso delle promesse, tutti i gestori delle stesse promesse vengono combinati in un unico "script").
reject-promise
: come perresolve-promise
, ma per il rifiuto.classic-script
: valutazione dello script (ad es.<script>
oimport()
)module-script
: comeclassic-script
, ma per gli script dei moduli.
- Dati relativi ai tempi separati per lo script:
startTime
: ora in cui è stata richiamata la funzione di inserimento.duration
: la durata trastartTime
e il termine dell'elaborazione della coda di microtask successiva.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 impiegato per mettere in "pausa" le operazioni sincrone (avviso, XHR sincrono).
- Dettagli dell'origine dello script:
sourceURL
: il nome della risorsa dello script, se disponibile (o vuoto se non trovato).sourceFunctionName
: il nome della funzione dello script, se 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 un<iframe>
) in cui si è verificato il frame dell'animazione lungo.window
: un riferimento alla finestra dello stesso dominio.
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 di rendimento 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. In questo modo puoi identificare e riprodurre i problemi di interattività che altrimenti potresti non scoprire.
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
}
Link all'interazione INP più lunga
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 valido è quello a cui viene data risposta a tutte le interazioni in 200 millisecondi o meno dall'interazione fino alla visualizzazione del frame 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:
In alcuni casi è possibile che un evento INP abbracci due LoAF, in genere se l'interazione si verifica dopo che il frame ha iniziato la parte di rendering del frame precedente, quindi il gestore dell'evento viene elaborato nel frame successivo:
In alcuni rari casi, è persino possibile che includa più di due LoAF.
La registrazione dei dati LoAF associati all'interazione INP ti consente di ottenere molte più informazioni sull'interazione INP per facilitarne la diagnosi. Questo è particolarmente utile per comprendere il ritardo di inserimento: 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 dalla 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 lenta.
Invia dati di animazione più 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 enorme miglioramento, solo per scoprire che la prossima interazione più lenta è 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:
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 dei frame di animazione lunghi:
- Osservare frame di animazione lunghi con interazioni
- Osserva frame di animazione lunghi con durate di blocco elevate
- Osserva frame di animazione lunghi durante gli aggiornamenti critici dell'interfaccia utente per migliorare la fluidità
- Osserva i fotogrammi di animazione lunghi peggiori
- Identificare pattern comuni nei frame di animazione lunghi
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à, potrebbero esserci molti LoAF. Ti consigliamo di limitarti a quelli con interazioni, impostare una soglia elevata o esaminare solo i peggiori.
Man mano che risolvi i problemi di adattabilità più comuni, puoi espandere questo valore non limitandosi alle interazioni o alle durate di blocco elevate o abbassando le soglie.
Osservare frame di animazione lunghi con 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 anziché 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'analisi 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 è stato scelto perché è inferiore alla soglia INP "buona" di 200 millisecondi per contribuire a identificare potenziali frame problematici, mantenendo al minimo la quantità di frame di animazione lunghi registrati. 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. Per la fluidità, però, devi esaminare tutti i fotogrammi di 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 nell'evento visibilitychange
), il beacon 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 può essere particolarmente utile per le piattaforme personalizzabili in cui è possibile identificare temi o plug-in che causano problemi di prestazioni su una serie di siti.
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 di utilizzare strumenti per sviluppatori aggiuntivi 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. Con l'API di estensioni di DevTools, possono essere visualizzate anche in un canale a parte:
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 });
A lungo termine, è probabile che i frame di animazione lunghi vengano incorporati in DevTools stesso, ma nel frattempo lo snippet di codice precedente consente di visualizzarli lì.
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à. La prima attività lunga ha alcuni aggiornamenti di rendering da completare (in caso contrario, l'attuale frame di animazione lungo verrebbe reimpostato dopo e ne verrà avviato uno nuovo con l'attività successiva), ma invece di eseguire immediatamente l'azione di rendering, il browser ha elaborato una serie di attività aggiuntive e solo dopo ha eseguito l'azione di rendering lungo e ha terminato il frame di animazione lungo. Questo dimostra l'utilità di esaminare frame di animazione lunghi in DevTools, anziché solo attività lunghe, per identificare i rendering in ritardo.
Utilizzare i dati dei frame 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:
Utilizzare i dati dei frame di animazione lunghi negli strumenti di test automatico
Analogamente, gli strumenti di test automatico nelle pipeline CI/CD possono mostrare dettagli su potenziali problemi di prestazioni misurando frame 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 ultima analisi 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.
Sebbene l'API Long Tasks possa 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 fondamentalmente diversa dall'API Long Tasks esistente.
Perché non ho 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é ho voci di script, ma nessuna o poche informazioni sulle origini?
Ciò può accadere per una serie di motivi, tra cui il fatto che non esiste una fonte affidabile a cui fare riferimento.
Inoltre, le informazioni sugli script saranno limitate solo al sourceURL
(esclusi i reindirizzamenti) per gli script no-cors cross-origin
, con una stringa vuota per il sourceFunctionName
e un -1
per sourceCharPosition
. 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 API interessante con molti potenziali vantaggi rispetto all'API Long Tasks precedente.
Si sta rivelando uno strumento chiave per risolvere i problemi di reattività misurati dall'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.