Una scarsa reattività alle interazioni dà l'impressione che una pagina sia lenta o addirittura completamente non funzionante. Interaction to Next Paint (INP) è una metrica basata sull'API Event Timing. Misura l'interazione peggiore (meno alcuni outlier) come misura dell'adattabilità della pagina.
Identificare le cause principali di una pagina web che non risponde può essere difficile, soprattutto perché dipende dalle interazioni degli utenti e dalle condizioni ambientali, come le funzionalità del dispositivo e le condizioni della rete. Questo rende ancora più difficile la diagnosi rispetto a uno scenario più ripetibile e prevedibile come il caricamento pagina. I dati di laboratorio replicano solo un piccolo sottoinsieme di scenari utente reali, quindi è essenziale misurare le cause di un INP lento sul campo.
L'API Event Timing consente di suddividere la durata dell'INP in tre parti: ritardo di input (elaborazione già in corso al momento dell'interazione), durata dell'elaborazione (ritardi dovuti come risultato diretto dell'interazione) e ritardo di presentazione (ritardi dovuti al rendering del frame successivo dopo l'interazione). In questo modo è possibile identificare se il problema risiede in un altro codice, nel codice JavaScript dell'interazione o negli aggiornamenti del rendering dell'elaborazione del browser, anziché passare direttamente al codice dell'interazione.
È possibile raccogliere ulteriori informazioni su JavaScript, sul ricalcolo dello stile e sul lavoro di layout che ritarda un'interazione. Una traccia completa delle prestazioni che utilizza l'API JS Self-Profiling è una soluzione complessa che potrebbe causare problemi di prestazioni. L'API Long Animation Frames è un'API leggera che può essere utilizzata sul campo per identificare il codice JavaScript lento ed eseguire una distinzione tra i costi di ricalcolo dello stile e quelli di layout durante le interazioni INP:
- Stile e layout forzati a livello di script (
forcedStyleDurationeforcedLayoutDuration): segnala i ricalcoli sincroni dello stile (ad esempio la chiamata digetComputedStyle()dopo le mutazioni del DOM) e i layout/reflow forzati (ad esempio la lettura digetBoundingClientRect()ooffsetWidthdopo le mutazioni) all'interno di uno script in esecuzione durante il ritardo di input o la durata dell'elaborazione. - Stile e layout di rendering a livello di frame (
styleDurationelayoutDuration): indica il tempo impiegato per ricalcolare gli stili rispetto all'aggiornamento del layout durante l'aggiornamento del rendering del frame, contribuendo a spiegare un ritardo di presentazione elevato.
Distinguere il ricalcolo dello stile dal layout è fondamentale perché hanno cause principali e soluzioni diverse: una durata elevata dello stile indica una corrispondenza dei selettori CSS costosa o un'invalidazione dello stile ampia (risolta semplificando i selettori o riducendo l'ambito delle regole), mentre una durata elevata del layout indica calcoli geometrici costosi o un thrashing del layout sincrono (risolto raggruppando le letture DOM prima delle scritture, semplificando la struttura DOM o utilizzando il contenimento CSS).
Come implementare
Il calcolo di INP dall'API Event Timing non elaborata è complicato e presenta diverse sfumature. Ti consigliamo di utilizzare uno strumento o una libreria RUM per raccogliere questi dati.
web-vitals è una libreria open source di Google che calcola i Core Web Vitals, tra cui INP, e include anche parti secondarie e dati dei frame dell'animazione lunghi per l'interazione INP.
Ottieni attribuzioni per le interazioni INP utilizzando la libreria web-vitals
La libreria web-vitals è una piccola libreria utilizzata per misurare i Core Web Vitals e altre metriche sul rendimento. La funzione onINP() può essere utilizzata per identificare l'interazione più lenta e include informazioni sulle parti secondarie di INP, sugli script eseguiti durante l'interazione e sulle durate di stile e layout utilizzando l'API Long Animation Frames.
// Use the attribution build to get Long Animation Frame data
// alongside the INP metric value.
import { onINP } from 'web-vitals/attribution';
onINP((metric) => {
const { attribution } = metric;
const longestScript = attribution.longestScript;
// Sum rendering-phase style and layout durations across all LoAF entries
// intersecting the INP interaction (primarily explains presentationDelay).
let renderStyleDuration = 0;
let renderLayoutDuration = 0;
for (const entry of attribution.longAnimationFrameEntries) {
renderStyleDuration += entry.styleDuration ?? 0;
renderLayoutDuration += entry.layoutDuration ?? 0;
}
// Beacon script, style, and layout attribution for the INP interaction,
// so you can identify the root cause in production.
navigator.sendBeacon(
'/analytics',
JSON.stringify({
name: 'INP',
value: metric.value,
// These fields give the INP subparts:
inputDelay: attribution.inputDelay,
presentationDelay: attribution.presentationDelay,
processingDuration: attribution.processingDuration,
interactionTarget: attribution.interactionTarget,
// These fields identify which script function was responsible
// for the longest processing during the INP interaction.
invokerType: longestScript?.entry?.invokerType,
sourceURL: longestScript?.entry?.sourceURL,
sourceFunctionName: longestScript?.entry?.sourceFunctionName,
sourceCharPosition: longestScript?.entry?.sourceCharPosition,
// subpart indicates which phase (input delay, processing, or
// presentation delay) the longest script overlapped with most.
subpart: longestScript?.subpart,
intersectingDuration: longestScript?.intersectingDuration,
// Synchronous style and layout work forced inside the longest script
// (with forcedStyleAndLayoutDuration as a combined fallback):
forcedStyleDuration: longestScript?.entry?.forcedStyleDuration,
forcedLayoutDuration: longestScript?.entry?.forcedLayoutDuration,
forcedStyleAndLayoutDuration: longestScript?.entry?.forcedStyleAndLayoutDuration,
// Rendering-phase style and layout work across the interaction's frames
// (with totalStyleAndLayoutDuration as a combined fallback):
renderStyleDuration,
renderLayoutDuration,
totalStyleAndLayoutDuration: attribution.totalStyleAndLayoutDuration
})
);
});
Best practice
- SÌ: utilizza inizialmente le parti secondarie di INP per identificare se il ritardo è dovuto al JavaScript già in esecuzione (ritardo di input), al JavaScript dei gestori di eventi per l'interazione (durata dell'elaborazione) o al rendering successivo (ritardo di presentazione).
- PROVA a identificare il JavaScript di blocco più grande come dettaglio aggiuntivo, in particolare per il ritardo dell'input e la durata dell'elaborazione.
- FAI distinzione tra ricalcolo dello stile (
styleDuration,forcedStyleDuration) e layout (layoutDuration,forcedLayoutDuration) quando diagnostichi una durata di elaborazione elevata o un ritardo di presentazione: tempi di stile elevati indicano selettori CSS costosi o invalidazioni ampie, mentre tempi di layout elevati indicano colli di bottiglia della geometria DOM o thrashing del layout sincrono. - SÌ: preferisci l'API Long Animation Frames per fornire questi ulteriori dettagli rispetto ad alternative come l'API JS Self-Profiling, che comporta un overhead di runtime più elevato.
- SÌ: utilizza la libreria
web-vitalsse non sono presenti altre soluzioni RUM. Può identificare l'interazione INP e include informazioni sulle parti secondarie e sugli script eseguiti durante l'interazione (utilizzando l'API Long Animation Frames). - SÌ: invia le informazioni richieste a un servizio di analisi anziché limitarti a registrarle localmente.
Supporto del browser e strategie di riserva
L'API Event Timing è disponibile nella maggior parte dei browser moderni ed è necessaria per calcolare l'INP e le relative parti secondarie. Per i browser che non supportano questa API, l'INP non può essere misurato.
L'API Long Animation Frames fornisce dettagli aggiuntivi facoltativi. Può essere utilizzato in sicurezza senza fallback. Nella maggior parte dei casi, le opportunità di miglioramento del rendimento identificate si applicano anche ad altri browser.
Se il tuo target Baseline supporta l'API Long Animation Frames (long-animation-frames), ma non supporta proprietà separate per la durata di stile e layout (styleDuration e layoutDuration su PerformanceLongAnimationFrameTiming o forcedStyleDuration e forcedLayoutDuration su PerformanceScriptTiming), utilizza i tempi combinati di stile e layout:
- Utilizza
script.forcedStyleAndLayoutDurationsuPerformanceScriptTimingper il lavoro sincrono forzato su stile e layout all'interno degli script. - Utilizza
metric.attribution.totalStyleAndLayoutDurationinweb-vitals/attribution(o calcola(entry.paintTime || entry.startTime + entry.duration) - entry.styleAndLayoutStartsu ogni vocePerformanceLongAnimationFrameTiming) per un lavoro combinato di stile e layout.