UNPKG

web-vitals

Version:

Easily measure performance metrics in JavaScript

2 lines (1 loc) 6.03 kB
!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports):"function"==typeof define&&define.amd?define(["exports"],t):t((e="undefined"!=typeof globalThis?globalThis:e||self).webVitals={})}(this,function(e){"use strict";let t=-1;const n=e=>{addEventListener("pageshow",n=>{n.persisted&&(t=n.timeStamp,e(n))},!0)},i=(e,t,n,i)=>{let o,s;return r=>{t.value>=0&&(r||i)&&(s=t.value-(o??0),(s||void 0===o)&&(o=t.value,t.delta=s,t.rating=((e,t)=>e>t[1]?"poor":e>t[0]?"needs-improvement":"good")(t.value,n),e(t)))}},o=e=>{requestAnimationFrame(()=>requestAnimationFrame(e))},s=()=>{const e=performance.getEntriesByType("navigation")[0];if(e&&e.responseStart>0&&e.responseStart<performance.now())return e},r=()=>s()?.activationStart??0,c=(e,n=-1)=>{const i=s();let o="navigate";t>=0?o="back-forward-cache":i&&(document.prerendering||r()>0?o="prerender":document.wasDiscarded?o="restore":i.type&&(o=i.type.replace(/_/g,"-")));return{name:e,value:n,rating:"good",delta:0,entries:[],id:`v5-${Date.now()}-${Math.floor(8999999999999*Math.random())+1e12}`,navigationType:o}},a=new WeakMap;function d(e,t){return a.get(e)||a.set(e,new t),a.get(e)}class f{t;i=0;o=[];h(e){if(e.hadRecentInput)return;const t=this.o[0],n=this.o.at(-1);this.i&&t&&n&&e.startTime-n.startTime<1e3&&e.startTime-t.startTime<5e3?(this.i+=e.value,this.o.push(e)):(this.i=e.value,this.o=[e]),this.t?.(e)}}const h=(e,t,n={})=>{try{if(PerformanceObserver.supportedEntryTypes.includes(e)){const i=new PerformanceObserver(e=>{queueMicrotask(()=>{t(e.getEntries())})});return i.observe({type:e,buffered:!0,...n}),i}}catch{}},l=e=>{let t=!1;return()=>{t||(e(),t=!0)}};let u=-1;const p=new Set,m=()=>"hidden"!==document.visibilityState||document.prerendering?1/0:0,g=e=>{if("hidden"===document.visibilityState){if("visibilitychange"===e.type)for(const e of p)e();isFinite(u)||(u="visibilitychange"===e.type?e.timeStamp:0,removeEventListener("prerenderingchange",g,!0))}},v=()=>{if(u<0){const e=r(),t=document.prerendering?void 0:globalThis.performance.getEntriesByType("visibility-state").find(t=>"hidden"===t.name&&t.startTime>=e)?.startTime;u=t??m(),addEventListener("visibilitychange",g,!0),addEventListener("prerenderingchange",g,!0),n(()=>{setTimeout(()=>{u=m()})})}return{get firstHiddenTime(){return u},onHidden(e){p.add(e)}}},y=e=>{document.prerendering?addEventListener("prerenderingchange",e,!0):e()},T=[1800,3e3],b=(e,t={})=>{y(()=>{const s=v();let a,d=c("FCP");const f=h("paint",e=>{for(const t of e)"first-contentful-paint"===t.name&&(f.disconnect(),t.startTime<s.firstHiddenTime&&(d.value=Math.max(t.startTime-r(),0),d.entries.push(t),a(!0)))});f&&(a=i(e,d,T,t.reportAllChanges),n(n=>{d=c("FCP"),a=i(e,d,T,t.reportAllChanges),o(()=>{d.value=performance.now()-n.timeStamp,a(!0)})}))})},E=[.1,.25];let L=0,P=1/0,_=0;const M=e=>{for(const t of e)t.interactionId&&(P=Math.min(P,t.interactionId),_=Math.max(_,t.interactionId),L=_?(_-P)/7+1:0)};let w;const C=()=>w?L:performance.interactionCount??0,I=()=>{"interactionCount"in performance||w||(w=h("event",M,{durationThreshold:0}))};let F=0;class k{l=[];u=new Map;p;m;v(){F=C(),this.l.length=0,this.u.clear()}T(){const e=Math.min(this.l.length-1,Math.floor((C()-F)/50));return this.l[e]}h(e){if(this.p?.(e),!e.interactionId&&"first-input"!==e.entryType)return;const t=this.l.at(-1);let n=this.u.get(e.interactionId);if(n||this.l.length<10||e.duration>t.L){if(n?e.duration>n.L?(n.entries=[e],n.L=e.duration):e.duration===n.L&&e.startTime===n.entries[0].startTime&&n.entries.push(e):(n={id:e.interactionId,entries:[e],L:e.duration},this.u.set(n.id,n),this.l.push(n)),this.l.sort((e,t)=>t.L-e.L),this.l.length>10){const e=this.l.splice(10);for(const t of e)this.u.delete(t.id)}this.m?.(n)}}}const x=e=>{const t=globalThis.requestIdleCallback||setTimeout,n=globalThis.cancelIdleCallback||clearTimeout;if("hidden"===document.visibilityState)e();else{const i=l(e);let o=-1;const s=()=>{n(o),i()};addEventListener("visibilitychange",s,{once:!0,capture:!0}),o=t(()=>{removeEventListener("visibilitychange",s,{capture:!0}),i()})}},A=[200,500];class B{p;h(e){this.p?.(e)}}const S=[2500,4e3],q=[800,1800],N=e=>{document.prerendering?y(()=>N(e)):"complete"!==document.readyState?addEventListener("load",()=>N(e),!0):setTimeout(e)};e.CLSThresholds=E,e.FCPThresholds=T,e.INPThresholds=A,e.LCPThresholds=S,e.TTFBThresholds=q,e.onCLS=(e,t={})=>{const s=v();b(l(()=>{let r,a=c("CLS",0);const l=d(t,f),u=e=>{for(const t of e)l.h(t);l.i>a.value&&(a.value=l.i,a.entries=l.o,r())},p=h("layout-shift",u);p&&(r=i(e,a,E,t.reportAllChanges),s.onHidden(()=>{u(p.takeRecords()),r(!0)}),n(()=>{l.i=0,a=c("CLS",0),r=i(e,a,E,t.reportAllChanges),o(r)}),setTimeout(r))}))},e.onFCP=b,e.onINP=(e,t={})=>{if(!globalThis.PerformanceEventTiming||!("interactionId"in PerformanceEventTiming.prototype))return;const o=v();y(()=>{I();let s,r=c("INP");const a=d(t,k),f=e=>{x(()=>{for(const t of e)a.h(t);const t=a.T();t&&t.L!==r.value&&(r.value=t.L,r.entries=t.entries,s())})},l=h("event",f,{durationThreshold:t.durationThreshold??40});s=i(e,r,A,t.reportAllChanges),l&&(l.observe({type:"first-input",buffered:!0}),o.onHidden(()=>{f(l.takeRecords()),s(!0)}),n(()=>{a.v(),r=c("INP"),s=i(e,r,A,t.reportAllChanges)}))})},e.onLCP=(e,t={})=>{y(()=>{const s=v();let a,f=c("LCP");const u=d(t,B),p=e=>{t.reportAllChanges||(e=e.slice(-1));for(const t of e)u.h(t),t.startTime<s.firstHiddenTime&&(f.value=Math.max(t.startTime-r(),0),f.entries=[t],a())},m=h("largest-contentful-paint",p);if(m){a=i(e,f,S,t.reportAllChanges);const s=l(()=>{p(m.takeRecords()),m.disconnect(),a(!0)}),r=e=>{e.isTrusted&&(x(s),removeEventListener(e.type,r,{capture:!0}))};for(const e of["keydown","click","visibilitychange"])addEventListener(e,r,{capture:!0});n(n=>{f=c("LCP"),a=i(e,f,S,t.reportAllChanges),o(()=>{f.value=performance.now()-n.timeStamp,a(!0)})})}})},e.onTTFB=(e,t={})=>{let o=c("TTFB"),a=i(e,o,q,t.reportAllChanges);N(()=>{const d=s();d&&(o.value=Math.max(d.responseStart-r(),0),o.entries=[d],a(!0),n(()=>{o=c("TTFB",0),a=i(e,o,q,t.reportAllChanges),a(!0)}))})}});