Oppdag hvordan Performance Observer API gir en kraftig, ikke-påtrengende måte å overvåke runtime web performance, spore Core Web Vitals og optimalisere brukeropplevelsen.
Låse opp Web Performance: En dypdykk i Performance Observer API
I dagens fartsfylte digitale verden er web performance ikke en luksus; det er en nødvendighet. En treg eller ikke-responsiv nettside kan føre til brukerfrustrasjon, høyere avvisningsfrekvens og en direkte negativ innvirkning på forretningsmål, enten det er salg, annonseinntekter eller brukerengasjement. I årevis har utviklere stolt på verktøy som måler ytelse på et enkelt tidspunkt, typisk under den første sideinnlasting. Selv om det er nyttig, går denne tilnærmingen glipp av en kritisk del av historien: brukernes hele opplevelse mens de samhandler med siden. Det er her runtime performance overvåking kommer inn, og dets kraftigste verktøy er Performance Observer API.
Tradisjonelle metoder involverer ofte polling for ytelsesdata med funksjoner som performance.getEntries(). Dette kan være ineffektivt, utsatt for å gå glipp av viktige hendelser som skjer mellom polling, og kan til og med legge til ytelsesoverhead som det prøver å måle. Performance Observer API revolusjonerer denne prosessen ved å tilby en asynkron, lav-overhead mekanisme for å abonnere på ytelseshendelser etter hvert som de skjer. Denne guiden vil ta deg med på et dypdykk inn i dette essensielle API-et, og vise deg hvordan du kan utnytte dets kraft til å overvåke Core Web Vitals, identifisere flaskehalser og til syvende og sist bygge raskere, mer hyggelige web-opplevelser for et globalt publikum.
Hva er Performance Observer API?
I kjernen er Performance Observer API et grensesnitt som gir en måte å observere og samle ytelsesmålingshendelser, kjent som ytelsesoppføringer. Tenk på det som en dedikert lytter for ytelsesrelaterte aktiviteter i nettleseren. I stedet for at du aktivt spør nettleseren: "Har det skjedd noe ennå?", forteller nettleseren deg proaktivt: "En ny ytelseshendelse skjedde nettopp! Her er detaljene."
Dette oppnås gjennom et observatørmønster. Du oppretter en observatørinstans, forteller den hvilke typer ytelseshendelser du er interessert i (f.eks. store malinger, brukerinndata, layoutskift), og gir en tilbakemeldingsfunksjon. Når en ny hendelse av en spesifisert type registreres i nettleserens ytelsestidslinje, blir tilbakemeldingsfunksjonen din kalt med en liste over de nye oppføringene. Denne asynkrone, push-baserte modellen er langt mer effektiv og pålitelig enn den eldre pull-baserte modellen for gjentatte ganger å kalle performance.getEntries().
Den gamle måten vs. Den nye måten
For å sette pris på innovasjonen til Performance Observer, la oss kontrastere de to tilnærmingene:
- Den gamle måten (Polling): Du kan bruke setTimeout eller requestAnimationFrame til periodisk å kalle performance.getEntriesByName('my-metric') for å se om metrikken din er registrert. Dette er problematisk fordi du kanskje sjekker for sent og går glipp av hendelsen, eller sjekker for ofte og kaster bort CPU-sykluser. Du risikerer også å fylle opp nettleserens ytelsesbuffer hvis du ikke rydder oppføringer regelmessig.
- Den nye måten (Observing): Du setter opp en PerformanceObserver én gang. Den sitter stille i bakgrunnen og bruker minimalt med ressurser. Så snart en relevant ytelsesoppføring registreres – enten det er ett millisekund etter sideinnlasting eller ti minutter inn i en brukers sesjon – blir koden din varslet umiddelbart. Dette sikrer at du aldri går glipp av en hendelse, og at overvåkingskoden din er så effektiv som mulig.
Hvorfor du bør bruke Performance Observer
Å integrere Performance Observer API i utviklingsarbeidsflyten din tilbyr en mengde fordeler som er avgjørende for moderne webapplikasjoner som sikter mot en global rekkevidde.
- Ikke-påtrengende overvåking: Observatørens tilbakemeldingsfunksjon utføres vanligvis i inaktive perioder, noe som sikrer at ytelsesovervåkingskoden din ikke forstyrrer brukeropplevelsen eller blokkerer hovedtråden. Den er designet for å være lett og ha et ubetydelig ytelsesfotavtrykk.
- Omfattende runtime-data: Nettsiden er dynamisk. Ytelsesproblemer skjer ikke bare ved innlastingstidspunktet. En bruker kan utløse en kompleks animasjon, laste inn mer innhold ved å rulle eller samhandle med en tung komponent lenge etter at den første siden er lastet inn. Performance Observer fanger disse runtime-hendelsene, og gir deg et komplett bilde av hele brukersesjonen.
- Fremtidssikker og standardisert: Det er W3C-anbefalt standard for innsamling av ytelsesdata. Nye ytelsesmetrikker og API-er er utformet for å integreres med den, noe som gjør den til et bærekraftig og fremtidsrettet valg for prosjektene dine.
- Grunnlaget for Real User Monitoring (RUM): For virkelig å forstå hvordan nettstedet ditt presterer for brukere på tvers av forskjellige land, enheter og nettverksforhold, trenger du data fra reelle sesjoner. Performance Observer er det ideelle verktøyet for å bygge en robust RUM-løsning, slik at du kan samle inn viktige metrikker og sende dem til en analysetjeneste for aggregering og analyse.
- Eliminerer race conditions: Med polling kan du prøve å få tilgang til en ytelsesoppføring før den er registrert. Observatørmodellen eliminerer denne race condition fullstendig, ettersom koden din bare kjører etter at oppføringen er tilgjengelig.
Komme i gang: Det grunnleggende om Performance Observer
Å bruke API-et er greit frem. Prosessen innebærer tre hovedtrinn: å opprette en observatør, definere en tilbakemeldingsfunksjon og fortelle observatøren hva han skal se etter.
1. Opprette en observatør med en tilbakemeldingsfunksjon
Først instansierer du et PerformanceObserver-objekt og sender det en tilbakemeldingsfunksjon. Denne funksjonen vil bli utført når nye oppføringer oppdages.
const observer = new PerformanceObserver((entryList) => { for (const entry of entryList.getEntries()) { console.log('Entry Type:', entry.entryType); console.log('Entry Name:', entry.name); console.log('Start Time:', entry.startTime); console.log('Duration:', entry.duration); } });
Tilbakemeldingsfunksjonen mottar et PerformanceObserverEntryList-objekt. Du kan kalle getEntries()-metoden på denne listen for å få en matrise med alle de nylig observerte ytelsesoppføringene.
2. Observere spesifikke oppføringstyper
En observatør gjør ingenting før du forteller den hva du skal overvåke. Du gjør dette ved å bruke .observe()-metoden. Denne metoden tar et objekt med en entryTypes-egenskap (eller i noen moderne tilfeller bare type for en enkelt type), som er en matrise med strenger som representerer de ytelsesoppføringstypene du er interessert i.
// Start observing two types of entries observer.observe({ entryTypes: ['mark', 'measure'] });
Noen av de vanligste oppføringstypene inkluderer:
- 'resource': Detaljer om nettverksforespørsler for ressurser som skript, bilder og stilark.
- 'paint': Timing for first-paint og first-contentful-paint.
- 'largest-contentful-paint': Core Web Vital-metrikken for oppfattet innlastingshastighet.
- 'layout-shift': Core Web Vital-metrikken for visuell stabilitet.
- 'first-input': Informasjon om den første brukerinteraksjonen, brukt for First Input Delay Core Web Vital.
- 'longtask': Identifiserer oppgaver på hovedtråden som tar lenger tid enn 50 millisekunder, noe som kan forårsake manglende respons.
- 'mark' & 'measure': Egendefinerte markører og målinger du definerer i din egen kode ved hjelp av User Timing API.
3. Stopp observatøren
Når du ikke lenger trenger å samle inn data, er det god praksis å koble fra observatøren for å frigjøre ressurser.
observer.disconnect();
Praktiske brukstilfeller: Overvåking av Core Web Vitals
Core Web Vitals er et sett med spesifikke faktorer som Google anser som viktige i en nettsides generelle brukeropplevelse. Å overvåke dem er en av de kraftigste bruksområdene for Performance Observer API. La oss se hvordan vi måler hver enkelt.
Overvåking av Largest Contentful Paint (LCP)
LCP måler innlastingytelsen. Den markerer punktet i sideinnlastingstidslinjen når hovedinnholdet sannsynligvis er lastet inn. En god LCP-score er 2,5 sekunder eller mindre.
LCP-elementet kan endres etter hvert som siden lastes inn. I utgangspunktet kan en overskrift være LCP-elementet, men senere kan et større bilde lastes inn og bli det nye LCP-elementet. Dette er grunnen til at en Performance Observer er perfekt – den varsler deg om hver potensielle LCP-kandidat etter hvert som den gjengis.
// Observe LCP and log the final value let lcpValue = 0; const lcpObserver = new PerformanceObserver((entryList) => { const entries = entryList.getEntries(); // The last entry is the most up-to-date LCP candidate const lastEntry = entries[entries.length - 1]; lcpValue = lastEntry.startTime; console.log(`LCP updated: ${lcpValue.toFixed(2)}ms`, lastEntry.element); }); lcpObserver.observe({ type: 'largest-contentful-paint', buffered: true }); // It's good practice to disconnect the observer after the user interacts, // as interactions can stop new LCP candidates from being dispatched. // window.addEventListener('beforeunload', () => lcpObserver.disconnect());
Merk bruken av buffered: true. Dette er et viktig alternativ som instruerer observatøren til å inkludere oppføringer som ble registrert *før* observe()-metoden ble kalt. Dette forhindrer at du går glipp av en tidlig LCP-hendelse.
Overvåking av First Input Delay (FID) og Interaction to Next Paint (INP)
Disse metrikkene måler interaktivitet. De kvantifiserer brukerens opplevelse når de først prøver å samhandle med siden.
First Input Delay (FID) måler tiden fra når en bruker først samhandler med en side (f.eks. klikker på en knapp) til tiden da nettleseren faktisk er i stand til å begynne å behandle hendelseshåndterere som svar på den interaksjonen. En god FID er 100 millisekunder eller mindre.
Interaction to Next Paint (INP) er en nyere, mer omfattende metrikk som har erstattet FID som en Core Web Vital i mars 2024. Mens FID bare måler *forsinkelsen* til den *første* interaksjonen, vurderer INP den *totale latenstiden* til *alle* brukerinteraksjoner gjennom hele sidens livssyklus, og rapporterer den verste. Dette gir et bedre bilde av den generelle responsen. En god INP er 200 millisekunder eller mindre.
Du kan overvåke FID ved å bruke 'first-input' oppføringstypen:
// Observe FID const fidObserver = new PerformanceObserver((entryList) => { for (const entry of entryList.getEntries()) { const fid = entry.processingStart - entry.startTime; console.log(`FID: ${fid.toFixed(2)}ms`); // Disconnect after the first input is reported fidObserver.disconnect(); } }); fidObserver.observe({ type: 'first-input', buffered: true });
Overvåking av INP er litt mer involvert ettersom den ser på hele varigheten av en hendelse. Du observerer 'event' oppføringstypen og beregner varigheten, og holder styr på den lengste.
// Simplified INP monitoring example let worstInp = 0; const inpObserver = new PerformanceObserver((entryList) => { for (const entry of entryList.getEntries()) { // The INP is the duration of the event const inp = entry.duration; // We only care about interactions longer than the current worst if (inp > worstInp) { worstInp = inp; console.log(`New worst INP: ${worstInp.toFixed(2)}ms`); } } }); inpObserver.observe({ type: 'event', durationThreshold: 16, buffered: true }); // durationThreshold helps filter out very short, likely insignificant events.
Overvåking av Cumulative Layout Shift (CLS)
CLS måler visuell stabilitet. Det hjelper med å kvantifisere hvor ofte brukere opplever uventede layoutskift – en frustrerende opplevelse der innhold flyttes på siden uten varsel. En god CLS-score er 0,1 eller mindre.
Poengsummen er en aggregering av alle individuelle layoutskiftpoeng. En Performance Observer er avgjørende her, da den rapporterer hvert skift etter hvert som det skjer.
// Observe and calculate the total CLS score let clsScore = 0; const clsObserver = new PerformanceObserver((entryList) => { for (const entry of entryList.getEntries()) { // We don't want to count shifts that were caused by user input if (!entry.hadRecentInput) { clsScore += entry.value; console.log(`Current CLS score: ${clsScore.toFixed(4)}`); } } }); clsObserver.observe({ type: 'layout-shift', buffered: true });
Egenskapen hadRecentInput er viktig. Den hjelper deg med å filtrere ut legitime layoutskift som skjer som svar på en brukers handling (som å klikke på en knapp som utvider en meny), som ikke skal telles med i CLS-poengsummen.
Bortom Core Web Vitals: Andre kraftige oppføringstyper
Mens Core Web Vitals er et flott utgangspunkt, kan Performance Observer overvåke mye mer. Her er noen andre utrolig nyttige oppføringstyper.
Sporing av lange oppgaver (`longtask`)
Long Tasks API eksponerer oppgaver som opptar hovedtråden i 50 millisekunder eller lenger. Disse er problematiske fordi mens hovedtråden er opptatt, kan ikke siden svare på brukerinndata, noe som fører til en treg eller frossen opplevelse. Å identifisere disse oppgavene er nøkkelen til å forbedre INP.
// Observe long tasks const longTaskObserver = new PerformanceObserver((entryList) => { for (const entry of entryList.getEntries()) { console.log(`Long Task Detected: ${entry.duration.toFixed(2)}ms`); // The 'attribution' property can sometimes tell you what caused the long task console.log('Attribution:', entry.attribution); } }); longTaskObserver.observe({ type: 'longtask', buffered: true });
Analysere ressurstider (`resource`)
Å forstå hvordan ressursene dine lastes inn er grunnleggende for ytelsesjustering. 'resource'-oppføringstypen gir deg detaljerte nettverkstidsdata for hver ressurs på siden din, inkludert DNS-oppslag, TCP-tilkobling og nedlastingstider for innhold.
// Observe resource timings const resourceObserver = new PerformanceObserver((entryList) => { for (const entry of entryList.getEntries()) { // Let's find slow-loading images if (entry.initiatorType === 'img' && entry.duration > 500) { console.warn(`Slow image detected: ${entry.name}`, `Duration: ${entry.duration.toFixed(2)}ms`); } } }); // Using 'buffered: true' is almost always necessary for resource timings // to catch assets that loaded before this script ran. resourceObserver.observe({ type: 'resource', buffered: true });
Måle egendefinerte ytelsesmerker (`mark` og `measure`)
Noen ganger må du måle ytelsen til applikasjonsspesifikk logikk. User Timing API lar deg opprette egendefinerte tidsstempler og måle varigheten mellom dem.
- performance.mark('start-operation'): Oppretter et tidsstempel kalt 'start-operation'.
- performance.mark('end-operation'): Oppretter et annet tidsstempel.
- performance.measure('my-operation', 'start-operation', 'end-operation'): Oppretter en måling mellom de to merkene.
Performance Observer kan lytte etter disse egendefinerte 'mark' og 'measure'-oppføringene, som er perfekte for å samle inn tidsdata om ting som komponentgjengivelsestider i et JavaScript-rammeverk eller varigheten av et kritisk API-kall og påfølgende databehandling.
// In your application code: performance.mark('start-data-processing'); // ... some complex data processing ... performance.mark('end-data-processing'); performance.measure('data-processing-duration', 'start-data-processing', 'end-data-processing'); // In your monitoring script: const customObserver = new PerformanceObserver((entryList) => { for (const entry of entryList.getEntriesByName('data-processing-duration')) { console.log(`Custom Measurement '${entry.name}': ${entry.duration.toFixed(2)}ms`); } }); customObserver.observe({ entryTypes: ['measure'] });
Avanserte konsepter og beste praksis
For å bruke Performance Observer API effektivt i et profesjonelt produksjonsmiljø, bør du vurdere denne beste praksisen.
- Vurder alltid `buffered: true`: For oppføringstyper som kan forekomme tidlig i sideinnlasting (som 'resource', 'paint' eller 'largest-contentful-paint'), er det viktig å bruke den bufrede flagget for å unngå å gå glipp av dem.
- Sjekk for nettleserstøtte: Selv om det er bredt støttet i moderne nettlesere, er det alltid lurt å sjekke for dets eksistens før du bruker det. Du kan også sjekke hvilke oppføringstyper som støttes av en bestemt nettleser.
- if ('PerformanceObserver' in window && PerformanceObserver.supportedEntryTypes.includes('longtask')) { // Safe to use PerformanceObserver for long tasks }
- Send data til en analysetjeneste: Logging av data til konsollen er flott for utvikling, men for overvåking i den virkelige verden, må du aggregere disse dataene. Den beste måten å sende denne telemetrien fra klienten på, er å bruke navigator.sendBeacon() API. Det er en ikke-blokkerende mekanisme designet for å sende små mengder data til en server, og den fungerer pålitelig selv når en side lastes ut.
- Grupper observatører etter bekymring: Selv om du kan bruke en enkelt observatør for flere oppføringstyper, er det ofte renere å opprette separate observatører for forskjellige bekymringer (f.eks. en for Core Web Vitals, en for ressurstider, en for egendefinerte metrikker). Dette forbedrer lesbarheten og vedlikeholdbarheten av koden.
- Forstå ytelsesoverhead: API-et er designet for å være svært lavt overhead. En veldig kompleks tilbakemeldingsfunksjon som utfører tunge beregninger, kan imidlertid potensielt påvirke ytelsen. Hold observatørtilbakemeldingsfunksjonene dine slanke og effektive. Utsett all tung prosessering til en web worker eller send rådataene til backend for prosessering der.
Konklusjon: Bygge en ytelses-først-kultur
Performance Observer API er mer enn bare et annet verktøy; det er et fundamentalt skifte i hvordan vi nærmer oss web performance. Det flytter oss fra reaktive, engangs målinger til proaktiv, kontinuerlig overvåking som gjenspeiler den sanne, dynamiske opplevelsen til brukerne våre over hele verden. Ved å tilby en pålitelig og effektiv måte å fange Core Web Vitals, lange oppgaver, ressurstider og egendefinerte metrikker, gir den utviklere mulighet til å identifisere og løse ytelsesflaskehalser før de påvirker et betydelig antall brukere.
Å ta i bruk Performance Observer API er et kritisk skritt mot å bygge en ytelses-først-kultur i ethvert utviklingsteam. Når du kan måle det som betyr noe, kan du forbedre det som betyr noe. Begynn å integrere disse observatørene i prosjektene dine i dag. Brukerne dine – uansett hvor de er i verden – vil takke deg for den raskere, jevnere og mer behagelige opplevelsen.