Een slechte reactiesnelheid op interacties leidt tot een slechte indruk van een pagina die traag is of zelfs helemaal niet werkt. Interaction to Next Paint (INP) is een statistiek die is gebaseerd op de Event Timing API. De statistiek meet de slechtste interactie (minus enkele uitschieters) als maatstaf voor de responsiviteit van de pagina.
Het kan lastig zijn om de hoofdoorzaken van een niet-reagerende webpagina te achterhalen, vooral omdat dit afhankelijk is van gebruikersinteracties en omgevingsomstandigheden, zoals apparaatmogelijkheden en netwerkomstandigheden. Dit maakt het nog moeilijker om de oorzaak vast te stellen dan bij een herhaalbaar en voorspelbaar scenario zoals het laden van een pagina. Labgegevens repliceren maar een kleine subset van echte gebruikersscenario's. Daarom is het essentieel om de oorzaken van een trage INP in de praktijk te meten.
Met de Event Timing API kun je de INP-duur opsplitsen in 3 subonderdelen: invoervertraging (verwerking die al plaatsvindt wanneer de interactie plaatsvindt), verwerkingsduur (vertragingen als direct gevolg van de interactie) en presentatievertraging (vertragingen die het gevolg zijn van de weergave van het volgende frame na de interactie). Zo kun je vaststellen of het probleem zich respectievelijk in andere code, de JavaScript-code van de interactie of de verwerking van de weergave-updates door de browser bevindt, in plaats van meteen naar de interactiecode te gaan.
Het is mogelijk om meer inzicht te krijgen in JavaScript, herberekening van stijl en vormgevingswerk dat een interactie vertraagt. Een volledige prestatietrace met de JS Self-Profiling API is een zware oplossing die prestatieproblemen kan veroorzaken. De Long Animation Frames API is een lichte API die in het veld kan worden gebruikt om langzame JavaScript te identificeren en onderscheid te maken tussen herberekening van de stijl en de kosten van de vormgeving tijdens INP-interacties:
- Geforceerde stijl en indeling op scriptniveau (
forcedStyleDurationenforcedLayoutDuration): Rapporteert synchrone herberekeningen van de stijl (zoals het aanroepen vangetComputedStyle()na DOM-mutaties) en geforceerde indelingen/reflows (zoals het lezen vangetBoundingClientRect()ofoffsetWidthna mutaties) in een actief script tijdens de invoervertraging of verwerkingsduur. - Weergavestijl en -indeling op frameniveau (
styleDurationenlayoutDuration): Rapporteert de tijd die is besteed aan het herberekenen van stijlen versus het updaten van de indeling tijdens de weergave-update van het frame. Dit helpt om een hoge presentatievertraging te verklaren.
Het is essentieel om herberekening van de stijl te onderscheiden van de indeling, omdat ze verschillende hoofdoorzaken en oplossingen hebben: een lange stijlduur wijst op dure CSS-kiezerovereenkomsten of brede stijl-ongeldigverklaring (opgelost door kiezers te vereenvoudigen of het regelbereik te verkleinen), terwijl een lange indelingsduur wijst op dure geometrieberekeningen of synchrone indelingsfouten (opgelost door DOM-lezingen te batchen vóór schrijfbewerkingen, de DOM-structuur te vereenvoudigen of CSS-containment te gebruiken).
Hoe wordt dit geïmplementeerd
Het berekenen van INP op basis van de onbewerkte Event Timing API is ingewikkeld en heeft verschillende nuances. We raden je aan een RUM-tool of -bibliotheek te gebruiken om deze gegevens te verzamelen.
web-vitals is een open-source bibliotheek van Google die de Core Web Vitals berekent, waaronder INP. De bibliotheek bevat ook subonderdelen en gegevens over lange animatieframes voor de INP-interactie.
Attributies voor INP-interacties krijgen met de web-vitals-bibliotheek
De web-vitals-bibliotheek is een kleine bibliotheek die wordt gebruikt om Core Web Vitals en andere prestatiestatistieken te meten. De functie onINP() kan worden gebruikt om de langzaamste interactie te identificeren en bevat informatie over de INP-subonderdelen, scripts die zijn uitgevoerd tijdens de interactie en stijl- en vormgevingsduur met de Long Animation Frames API.
// 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
})
);
});
Praktische tips
- WEL: Gebruik in eerste instantie INP-subonderdelen om te bepalen of de vertraging al JavaScript uitvoert (invoervertraging), de JavaScript-gebeurtenishandlers voor de interactie (verwerkingsduur) of de daaropvolgende weergave (presentatievertraging).
- Probeer het grootste blokkerende JavaScript te identificeren als aanvullend detail, met name voor invoervertraging en verwerkingsduur.
- Maak onderscheid tussen herberekening van stijl (
styleDuration,forcedStyleDuration) en indeling (layoutDuration,forcedLayoutDuration) als je een diagnose uitvoert van een lange verwerkingsduur of presentatievertraging: lange stijltijden duiden op dure CSS-kiezers of brede ongeldigverklaringen, terwijl lange indelingstijden duiden op knelpunten in de DOM-geometrie of synchrone indelingsthrashing. - WEL de Long Animation Frames API gebruiken om deze verdere details te bieden in plaats van alternatieven zoals de JS Self-Profiling API, die een hogere runtime-overhead heeft.
- Gebruik WEL de
web-vitals-bibliotheek als er geen andere RUM-oplossing is. De API kan de INP-interactie identificeren en bevat informatie over de subonderdelen en de scripts die tijdens de interactie zijn uitgevoerd (met de Long Animation Frames API). - WEL de vereiste informatie terugsturen naar een analyseservice in plaats van deze alleen lokaal te registreren.
Browserondersteuning en fallback-strategieën
De Event Timing API is beschikbaar in de meeste moderne browsers en is nodig om de INP en de INP-subonderdelen te berekenen. Voor browsers die deze API niet ondersteunen, kan de INP niet worden gemeten.
De Long Animation Frames API biedt optionele, aanvullende informatie. Deze kan veilig worden gebruikt zonder fallbacks. In de meeste gevallen zijn de prestatieverbeteringen die de tool vindt ook van toepassing op andere browsers.
Als je Baseline-doel de Long Animation Frames API (long-animation-frames) ondersteunt, maar geen afzonderlijke eigenschappen voor stijl- en opmaakduur ondersteunt (styleDuration en layoutDuration op PerformanceLongAnimationFrameTiming, of forcedStyleDuration en forcedLayoutDuration op PerformanceScriptTiming), val je terug op de gecombineerde stijl- en opmaaktiming:
- Gebruik
script.forcedStyleAndLayoutDurationopPerformanceScriptTimingvoor synchrone geforceerde stijl- en lay-outwerkzaamheden in scripts. - Gebruik
metric.attribution.totalStyleAndLayoutDurationinweb-vitals/attribution(of bereken(entry.paintTime || entry.startTime + entry.duration) - entry.styleAndLayoutStartvoor elkPerformanceLongAnimationFrameTiming-item) voor gecombineerde stijl- en vormgevingswerkzaamheden.