UNPKG

web-vitals-element

Version:

> Bring [web vitals](https://github.com/GoogleChrome/web-vitals) quickly into your page using custom elements

2 lines (1 loc) 6.98 kB
var e,t,n,i,r=function(e,t){return{name:e,value:void 0===t?-1:t,delta:0,entries:[],id:"v2-".concat(Date.now(),"-").concat(Math.floor(8999999999999*Math.random())+1e12)}},a=function(e,t){try{if(PerformanceObserver.supportedEntryTypes.includes(e)){if("first-input"===e&&!("PerformanceEventTiming"in self))return;var n=new PerformanceObserver((function(e){return e.getEntries().map(t)}));return n.observe({type:e,buffered:!0}),n}}catch(e){}},o=function(e,t){var n=function n(i){"pagehide"!==i.type&&"hidden"!==document.visibilityState||(e(i),t&&(removeEventListener("visibilitychange",n,!0),removeEventListener("pagehide",n,!0)))};addEventListener("visibilitychange",n,!0),addEventListener("pagehide",n,!0)},s=function(e){addEventListener("pageshow",(function(t){t.persisted&&e(t)}),!0)},u="function"==typeof WeakSet?new WeakSet:new Set,c=function(e,t,n){var i;return function(){t.value>=0&&(n||u.has(t)||"hidden"===document.visibilityState)&&(t.delta=t.value-(i||0),(t.delta||void 0===i)&&(i=t.value,e(t)))}},d=-1,p=function(){return"hidden"===document.visibilityState?0:1/0},m=function(){o((function(e){var t=e.timeStamp;d=t}),!0)},f=function(){return d<0&&(d=p(),m(),s((function(){setTimeout((function(){d=p(),m()}),0)}))),{get firstHiddenTime(){return d}}},l=function(e,t){var n,i=f(),o=r("FCP"),d=function(e){"first-contentful-paint"===e.name&&(m&&m.disconnect(),e.startTime<i.firstHiddenTime&&(o.value=e.startTime,o.entries.push(e),u.add(o),n()))},p=performance.getEntriesByName&&performance.getEntriesByName("first-contentful-paint")[0],m=p?null:a("paint",d);(p||m)&&(n=c(e,o,t),p&&d(p),s((function(i){o=r("FCP"),n=c(e,o,t),requestAnimationFrame((function(){requestAnimationFrame((function(){o.value=performance.now()-i.timeStamp,u.add(o),n()}))}))})))},v=!1,h=-1,g={passive:!0,capture:!0},y=new Date,b=function(i,r){e||(e=r,t=i,n=new Date,L(removeEventListener),T())},T=function(){if(t>=0&&t<n-y){var r={entryType:"first-input",name:e.type,target:e.target,cancelable:e.cancelable,startTime:e.timeStamp,processingStart:e.timeStamp+t};i.forEach((function(e){e(r)})),i=[]}},w=function(e){if(e.cancelable){var t=(e.timeStamp>1e12?new Date:performance.now())-e.timeStamp;"pointerdown"==e.type?function(e,t){var n=function(){b(e,t),r()},i=function(){r()},r=function(){removeEventListener("pointerup",n,g),removeEventListener("pointercancel",i,g)};addEventListener("pointerup",n,g),addEventListener("pointercancel",i,g)}(t,e):b(t,e)}},L=function(e){["mousedown","keydown","touchstart","pointerdown"].forEach((function(t){return e(t,w,g)}))},E=Object.freeze({__proto__:null,getCLS:function(e,t){v||(l((function(e){h=e.value})),v=!0);var n,i=function(t){h>-1&&e(t)},u=r("CLS",0),d=0,p=[],m=function(e){if(!e.hadRecentInput){var t=p[0],i=p[p.length-1];d&&e.startTime-i.startTime<1e3&&e.startTime-t.startTime<5e3?(d+=e.value,p.push(e)):(d=e.value,p=[e]),d>u.value&&(u.value=d,u.entries=p,n())}},f=a("layout-shift",m);f&&(n=c(i,u,t),o((function(){f.takeRecords().map(m),n()})),s((function(){d=0,h=-1,u=r("CLS",0),n=c(i,u,t)})))},getFCP:l,getFID:function(n,d){var p,m=f(),l=r("FID"),v=function(e){e.startTime<m.firstHiddenTime&&(l.value=e.processingStart-e.startTime,l.entries.push(e),u.add(l),p())},h=a("first-input",v);p=c(n,l,d),h&&o((function(){h.takeRecords().map(v),h.disconnect()}),!0),h&&s((function(){var a;l=r("FID"),p=c(n,l,d),i=[],t=-1,e=null,L(addEventListener),a=v,i.push(a),T()}))},getLCP:function(e,t){var n,i=f(),d=r("LCP"),p=function(e){var t=e.startTime;t<i.firstHiddenTime&&(d.value=t,d.entries.push(e)),n()},m=a("largest-contentful-paint",p);if(m){n=c(e,d,t);var l=function(){u.has(d)||(m.takeRecords().map(p),m.disconnect(),u.add(d),n())};["keydown","click"].forEach((function(e){addEventListener(e,l,{once:!0,capture:!0})})),o(l,!0),s((function(i){d=r("LCP"),n=c(e,d,t),requestAnimationFrame((function(){requestAnimationFrame((function(){d.value=performance.now()-i.timeStamp,u.add(d),n()}))}))}))}},getTTFB:function(e){var t,n=r("TTFB");t=function(){try{var t=performance.getEntriesByType("navigation")[0]||function(){var e=performance.timing,t={entryType:"navigation",startTime:0};for(var n in e)"navigationStart"!==n&&"toJSON"!==n&&(t[n]=Math.max(e[n]-e.navigationStart,0));return t}();if(n.value=n.delta=t.responseStart,n.value<0)return;n.entries=[t],e(n)}catch(e){}},"complete"===document.readyState?setTimeout(t,0):addEventListener("pageshow",t)}});const S=new Map([["CLS",{thresholds:{good:.1,needsImprovement:.25},observerEntryType:"layout-shift",explainerURL:"https://web.dev/cls/",longName:"Cumulative Layout Shift",roundFn:e=>Math.floor(100*e)/100}],["FCP",{thresholds:{good:2500},observerEntryType:"paint",explainerURL:"https://web.dev/fcp/",unit:"ms",longName:"First Contentful Paint"}],["FID",{thresholds:{good:100,needsImprovement:300},observerEntryType:"first-input",explainerURL:"https://web.dev/fid/",unit:"ms",longName:"First Input Delay"}],["LCP",{thresholds:{good:2500,needsImprovement:4e3},observerEntryType:"paint",explainerURL:"https://web.dev/lcp/",unit:"ms",longName:"Largest Contentful Paint"}],["TTFB",{thresholds:{good:2500},explainerURL:"https://web.dev/time-to-first-byte/",unit:"ms",longName:"Time to first byte"}]]),F=["class","style"],M=["show-unsupported","show-metric-name"];class C extends HTMLElement{constructor(){super(),this.unsupportedMetrics=[],this.metrics=new Map}connectedCallback(){const e=this.getMetricAttributes(),t=e.length?e:[...S.keys()];this.metrics=this.getMetrics(t),this.render();for(let e of this.metrics.values()){const{name:t,getWebVitalsValue:n}=e;n((n=>{this.metrics.set(t,{...e,...n}),this.render()}),!0)}}getMetricAttributes(){return this.getAttributeNames().filter((e=>!F.includes(e)&&!M.includes(e))).map((e=>e.toUpperCase()))}getMetrics(e){return new Map(e.reduce(((e,t)=>{const n=E[`get${t}`];if(!n)return console.error(`${t} is not supported by '<web-vitals />'`),this.unsupportedMetrics.push(t),e;const i=S.get(t),{observerEntryType:r}=i;return r&&!PerformanceObserver.supportedEntryTypes.includes(r)?(console.error(`${t} is not supported by your browser`),this.unsupportedMetrics.push(t),e):[...e,[t,{...S.get(t),getWebVitalsValue:n,name:t}]]}),[]))}render(){this.innerHTML=`<div class="web-vitals">\n <dl>\n ${[...this.metrics].map((([e,t])=>{const{explainerURL:n,longName:i,roundFn:r,thresholds:a,unit:o,value:s}=t;let u="";const c=r||Math.floor,{good:d,needsImprovement:p}=a;if(s){u+="is-final ";let e="is-poor";p&&s<=p&&(e="needs-improvement"),s<=d&&(e="is-good"),u+=e}return`\n <div class="${u}">\n <dt>\n ${this.hasAttribute("show-metric-name")?`${i} (<a href="${n}">${e}</a>)`:`<a href="${n}">${e}</a>`}\n </dt>\n <dd>${s?`${c(s)}${o||""}`:"..."}</dd>\n </div>\n `})).join("")}\n </dl>\n ${this.unsupportedMetrics.length&&this.hasAttribute("show-unsupported")?`<p>Not supported: ${this.unsupportedMetrics.join(", ")}</p>`:""}\n </div>`}}customElements.define("web-vitals",C);