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