diff --git a/package-lock.json b/package-lock.json index 98c32c6..480fbe6 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,15 +1,15 @@ { "name": "web-vitals-extension", - "version": "1.1.0", + "version": "1.2.0", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "web-vitals-extension", - "version": "1.1.0", + "version": "1.2.0", "license": "Apache-2.0", "dependencies": { - "web-vitals": "^3.0.0-beta.0" + "web-vitals": "^3.3.1" }, "devDependencies": { "babel-eslint": "^10.1.0", @@ -1621,9 +1621,9 @@ "dev": true }, "node_modules/web-vitals": { - "version": "3.0.0-beta.0", - "resolved": "https://registry.npmjs.org/web-vitals/-/web-vitals-3.0.0-beta.0.tgz", - "integrity": "sha512-Iq2uJxmAe0DnAX+Y06XByU4l+L8xqVXk+gW2qghnMR43blzh+HfOxl/KmkvcQYBFNgMYFULvPeHCH5FohaDkKw==" + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/web-vitals/-/web-vitals-3.3.1.tgz", + "integrity": "sha512-LTfY5GjcY3ngFzNsYFSYL+AmVmlWrzPTUxSMDis2rZbf+SzT7HH3NH4Y/l45XOlrAIunOBeURN9qtBHkRskAiA==" }, "node_modules/which": { "version": "1.3.1", @@ -2921,9 +2921,9 @@ "dev": true }, "web-vitals": { - "version": "3.0.0-beta.0", - "resolved": "https://registry.npmjs.org/web-vitals/-/web-vitals-3.0.0-beta.0.tgz", - "integrity": "sha512-Iq2uJxmAe0DnAX+Y06XByU4l+L8xqVXk+gW2qghnMR43blzh+HfOxl/KmkvcQYBFNgMYFULvPeHCH5FohaDkKw==" + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/web-vitals/-/web-vitals-3.3.1.tgz", + "integrity": "sha512-LTfY5GjcY3ngFzNsYFSYL+AmVmlWrzPTUxSMDis2rZbf+SzT7HH3NH4Y/l45XOlrAIunOBeURN9qtBHkRskAiA==" }, "which": { "version": "1.3.1", diff --git a/package.json b/package.json index febda72..059bbaa 100644 --- a/package.json +++ b/package.json @@ -12,7 +12,8 @@ "license": "Apache-2.0", "private": true, "scripts": { - "lint": "npx eslint src --fix" + "lint": "npx eslint src --fix", + "build": "npm install; cp node_modules/web-vitals/dist/web-vitals.attribution.js src/browser_action/web-vitals.js" }, "devDependencies": { "babel-eslint": "^10.1.0", @@ -20,6 +21,6 @@ "eslint-config-google": "^0.14.0" }, "dependencies": { - "web-vitals": "^3.0.0-beta.0" + "web-vitals": "^3.3.1" } } diff --git a/src/browser_action/vitals.js b/src/browser_action/vitals.js index 754116d..dd596c0 100644 --- a/src/browser_action/vitals.js +++ b/src/browser_action/vitals.js @@ -18,12 +18,13 @@ let latestCLS = {}; let enableLogging = localStorage.getItem('web-vitals-extension-debug')=='TRUE'; let enableUserTiming = localStorage.getItem('web-vitals-extension-user-timing')=='TRUE'; + let enableConsoleTables = localStorage.getItem('web-vitals-extension-console-tables')=='TRUE'; // Core Web Vitals thresholds - const LCP_THRESHOLD = 2500; - const FID_THRESHOLD = 100; - const INP_THRESHOLD = 200; - const CLS_THRESHOLD = 0.1; + const LCP_THRESHOLD = webVitals.LCPThresholds[0]; + const FID_THRESHOLD = webVitals.FIDThresholds[0]; + const INP_THRESHOLD = webVitals.INPThresholds[0]; + const CLS_THRESHOLD = webVitals.CLSThresholds[0]; // CLS update frequency const DEBOUNCE_DELAY = 500; @@ -118,8 +119,9 @@ enableOverlay: false, debug: false, userTiming: false, + consoleTables: false, }, ({ - enableOverlay, debug, userTiming, + enableOverlay, debug, userTiming, consoleTables, }) => { if (enableOverlay === true && overlayClosedForSession == false) { // Overlay @@ -162,13 +164,20 @@ localStorage.removeItem('web-vitals-extension-debug'); enableLogging = false; } - if (debug) { + if (userTiming) { localStorage.setItem('web-vitals-extension-user-timing', 'TRUE'); enableUserTiming = true; } else { localStorage.removeItem('web-vitals-extension-user-timing'); enableUserTiming = false; } + if (consoleTables) { + localStorage.setItem('web-vitals-extension-console-tables', 'TRUE'); + enableConsoleTables = true; + } else { + localStorage.removeItem('web-vitals-extension-console-tables'); + enableConsoleTables = false; + } }); } @@ -191,6 +200,15 @@ return date.toLocaleTimeString('en-US', {hourCycle: 'h23'}); } + /** + * Return a formatted string of the node with details in brackets + * @return {String} + */ + function formatNode(node) { + const nodeName = node?.localName || node?.nodeName; + const nodeDetails = node?.nodeValue || node?.innerText || node?.src; + return nodeDetails ? `${nodeName} (${nodeDetails})` : nodeName; + } /** * @@ -205,10 +223,10 @@ return; } if (enableLogging) { - console.log('[Web Vitals]', body.name, body.value.toFixed(2), body); + console.log('[Web Vitals Extension]', body.name, body.value.toFixed(2), body); } - if (enableUserTiming) { - addUserTimings(body); + if (enableUserTiming || enableConsoleTables) { + addUserTimings(body, enableUserTiming, enableConsoleTables); } badgeMetrics[metricName].value = body.value; badgeMetrics.location = getURL(); @@ -224,21 +242,90 @@ ); } - function addUserTimings(metric) { + function addUserTimings(metric, enableUserTiming, enableConsoleTables) { switch (metric.name) { case "LCP": - // LCP has a loadTime/renderTime (startTime), but not a duration. - // Could visualize relative to timeOrigin, or from loadTime -> renderTime. - // Skip for now. + if (metric.attribution && metric.attribution.lcpEntry && metric.attribution.navigationEntry) { + const navEntry = metric.attribution.navigationEntry; + // Set the start time to the later of the actual start time or the activationStart (for prerender) or 0 + const startTime = Math.max(navEntry.startTime, navEntry.activationStart) || 0; + // Add the performance marks for the Performance Panel + if (enableUserTiming) { + performance.measure(`[Web Vitals Extension] LCP.timeToFirstByte`, { + start: startTime, + duration: metric.attribution.timeToFirstByte, + }); + performance.measure(`[Web Vitals Extension] LCP.resourceLoadDelay`, { + start: startTime + metric.attribution.timeToFirstByte, + duration: metric.attribution.resourceLoadDelay, + }); + performance.measure(`[Web Vitals Extension] LCP.resourceLoadTime`, { + start: + startTime + + metric.attribution.timeToFirstByte + + metric.attribution.resourceLoadDelay, + duration: metric.attribution.resourceLoadTime, + }); + performance.measure(`[Web Vitals Extension] LCP.elmentRenderDelay`, { + duration: metric.attribution.elementRenderDelay, + end: metric.value + }); + } + // Add a nice console output + if (enableConsoleTables) { + console.table( + [ + { + 'LCP breakdown [Web Vitals Extension]': `LCP - ${metric.rating}`, + 'Time (ms)': Math.round(metric.value, 0), + 'Element': formatNode(metric.attribution.lcpEntry.element), + }, + { + 'LCP breakdown [Web Vitals Extension]': 'Time to First Byte', + 'Time (ms)': Math.round(metric.attribution.timeToFirstByte, 0), + }, + { + 'LCP breakdown [Web Vitals Extension]': 'Resource load delay', + 'Time (ms)': Math.round(metric.attribution.resourceLoadDelay, 0), + }, + { + 'LCP breakdown [Web Vitals Extension]': 'Resource load time', + 'Time (ms)': Math.round(metric.attribution.resourceLoadTime, 0), + }, + { + 'LCP breakdown [Web Vitals Extension]': 'Element render delay', + 'Time (ms)': Math.round(metric.attribution.elementRenderDelay, 0), + } + ] + ) + } + } break; case "CLS": - // CLS has a startTime, but not a duration. - // Could visualize the time between rendering tasks (Commit-to-Commit). - // Skip for now. + if (enableConsoleTables) { + // Add a nice console output of all the shifts + const shiftLength = metric.entries.length; + let entries = [{ + 'CLS breakdown [Web Vitals Extension]': `CLS (${shiftLength} ${ + shiftLength != 1 ? 'shifts' : 'shift' + }) - ${metric.rating}`, + 'Shift': Math.round(metric.value * 10000) / 10000, + }]; + metric.entries.map((entry, index) => { + entry.sources.map((source, index2) => { + entries.push({ + 'CLS breakdown [Web Vitals Extension]': `Layout shift ${index} element ${index2}`, + 'Element': formatNode(source.node), + "Shift": Math.round(entry.value * 10000) / 10000, + }); + }); + }); + console.table(entries) + } break; case "INP": - if (metric.entries.length > 0) { - const inpEntry = metric.entries[0]; + if (metric.attribution && metric.attribution.eventEntry) { + const inpEntry = metric.attribution.eventEntry; // RenderTime is an estimate, because duration is rounded, and may get rounded keydown // In rare cases it can be less than processingEnd and that breaks performance.measure(). @@ -246,31 +333,71 @@ const presentationTime = inpEntry.startTime + inpEntry.duration; const adjustedPresentationTime = Math.max(inpEntry.processingEnd + 4, presentationTime); - performance.measure(`[Web Vitals] INP.duration (${inpEntry.name})`, { - start: inpEntry.startTime, - end: presentationTime, - }); - performance.measure(`[Web Vitals] INP.inputDelay (${inpEntry.name})`, { - start: inpEntry.startTime, - end: inpEntry.processingStart, - }); - performance.measure(`[Web Vitals] INP.processingTime (${inpEntry.name})`, { - start: inpEntry.processingStart, - end: inpEntry.processingEnd, - }); - performance.measure(`[Web Vitals] INP.presentationDelay (${inpEntry.name})`, { - start: inpEntry.processingEnd, - end: adjustedPresentationTime, - }); + if (enableUserTiming) { + performance.measure(`[Web Vitals Extension] INP.duration (${inpEntry.name})`, { + start: inpEntry.startTime, + end: presentationTime, + }); + performance.measure(`[Web Vitals Extension] INP.inputDelay (${inpEntry.name})`, { + start: inpEntry.startTime, + end: inpEntry.processingStart, + }); + performance.measure(`[Web Vitals Extension] INP.processingTime (${inpEntry.name})`, { + start: inpEntry.processingStart, + end: inpEntry.processingEnd, + }); + performance.measure(`[Web Vitals Extension] INP.presentationDelay (${inpEntry.name})`, { + start: inpEntry.processingEnd, + end: adjustedPresentationTime, + }); + } + if (enableConsoleTables) { + // Add a nice console output + console.table( + [ + { + 'INP breakdown [Web Vitals Extension]': `INP - ${metric.rating}`, + 'Time (ms)': (presentationTime - inpEntry.startTime), + 'Element': formatNode(inpEntry.target), + }, + { + 'INP breakdown [Web Vitals Extension]': 'Input delay', + 'Time (ms)': (inpEntry.processingStart - inpEntry.startTime), + }, + { + 'INP breakdown [Web Vitals Extension]': 'Processing time', + 'Time (ms)': (inpEntry.processingEnd - inpEntry.processingStart), + }, + { + 'INP breakdown [Web Vitals Extension]': 'Presentation delay', + 'Time (ms)': (adjustedPresentationTime - inpEntry.processingEnd), + } + ] + ) + } } break; case "FID": - if (metric.entries.length > 0) { - const fidEntry = metric.entries[0] - performance.measure(`[Web Vitals Extension] FID (${fidEntry.name})`, { - start: fidEntry.startTime, - end: fidEntry.processingStart, - }); + if (metric.attribution && metric.attribution.eventEntry) { + const fidEntry = metric.attribution.eventEntry; + if (enableUserTiming) { + performance.measure(`[Web Vitals Extension] FID (${fidEntry.name})`, { + start: fidEntry.startTime, + end: fidEntry.processingStart, + }); + } + if (enableConsoleTables) { + // Add a nice console output + console.table( + [ + { + 'FID breakdown [Web Vitals Extension]': `FID - ${metric.rating}`, + 'Time (ms)': metric.value, + 'Element': formatNode(fidEntry.target), + }, + ] + ) + } } } } @@ -306,22 +433,22 @@ if (self._hasInstalledPerfMetrics) return; self._hasInstalledPerfMetrics = true; - webVitals.getCLS((metric) => { + webVitals.onCLS((metric) => { // As CLS values can fire frequently in the case // of animations or highly-dynamic content, we // debounce the broadcast of the metric. latestCLS = metric; debouncedCLSBroadcast(); - }, true); - webVitals.getLCP((metric) => { + }, { reportAllChanges: true }); + webVitals.onLCP((metric) => { broadcastMetricsUpdates('lcp', metric); - }, true); - webVitals.getFID((metric) => { + }, { reportAllChanges: true }); + webVitals.onFID((metric) => { broadcastMetricsUpdates('fid', metric); - }, true); - webVitals.getINP((metric) => { + }, { reportAllChanges: true }); + webVitals.onINP((metric) => { broadcastMetricsUpdates('inp', metric); - }, true); + }, { reportAllChanges: true }); } /** diff --git a/src/browser_action/web-vitals.js b/src/browser_action/web-vitals.js index 4ec2d73..eb99e54 100644 --- a/src/browser_action/web-vitals.js +++ b/src/browser_action/web-vitals.js @@ -1 +1 @@ -var e,n,t,i,a,r=!1,o=function(e){addEventListener("pageshow",(function(n){n.persisted&&(r=!0,e(n))}),!0)},c=function(){return window.performance&&(performance.getEntriesByType&&performance.getEntriesByType("navigation")[0]||function(){var e=performance.timing,n={entryType:"navigation",startTime:0};for(var t in e)"navigationStart"!==t&&"toJSON"!==t&&(n[t]=Math.max(e[t]-e.navigationStart,0));return n}())},u=function(e,n){var t=c();return{name:e,value:void 0===n?-1:n,delta:0,entries:[],id:"v2-".concat(Date.now(),"-").concat(Math.floor(8999999999999*Math.random())+1e12),navigationType:r?"back_forward_cache":t&&t.type}},f=function(e,n,t){try{if(PerformanceObserver.supportedEntryTypes.includes(e)){var i=new PerformanceObserver((function(e){n(e.getEntries())}));return i.observe(Object.assign({type:e,buffered:!0},t||{})),i}}catch(e){}},s=function(e,n){var t=function t(i){"pagehide"!==i.type&&"hidden"!==document.visibilityState||(e(i),n&&(removeEventListener("visibilitychange",t,!0),removeEventListener("pagehide",t,!0)))};addEventListener("visibilitychange",t,!0),addEventListener("pagehide",t,!0)},d=function(e,n,t){var i;return function(a){n.value>=0&&(a||t)&&(n.delta=n.value-(i||0),(n.delta||void 0===i)&&(i=n.value,e(n)))}},v=-1,m=function(){return"hidden"===document.visibilityState?0:1/0},p=function(){s((function(e){var n=e.timeStamp;v=n}),!0)},l=function(){return v<0&&(v=m(),p(),o((function(){setTimeout((function(){v=m(),p()}),0)}))),{get firstHiddenTime(){return v}}},h=function(e,n){var t,i=l(),a=u("FCP"),r=function(e){e.forEach((function(e){"first-contentful-paint"===e.name&&(s&&s.disconnect(),e.startTime-1&&e(n)},a=u("CLS",0),r=0,c=[],v=function(e){e.forEach((function(e){if(!e.hadRecentInput){var n=c[0],i=c[c.length-1];r&&e.startTime-i.startTime<1e3&&e.startTime-n.startTime<5e3?(r+=e.value,c.push(e)):(r=e.value,c=[e]),r>a.value&&(a.value=r,a.entries=c,t())}}))},m=f("layout-shift",v);m&&(t=d(i,a,n),s((function(){v(m.takeRecords()),t(!0)})),o((function(){r=0,g=-1,a=u("CLS",0),t=d(i,a,n)})))},E={passive:!0,capture:!0},w=new Date,S=function(i,a){e||(e=a,n=i,t=new Date,F(removeEventListener),L())},L=function(){if(n>=0&&n1e12?new Date:performance.now())-e.timeStamp;"pointerdown"==e.type?function(e,n){var t=function(){S(e,n),a()},i=function(){a()},a=function(){removeEventListener("pointerup",t,E),removeEventListener("pointercancel",i,E)};addEventListener("pointerup",t,E),addEventListener("pointercancel",i,E)}(n,e):S(n,e)}},F=function(e){["mousedown","keydown","touchstart","pointerdown"].forEach((function(n){return e(n,b,E)}))},I=function(t,a){var r,c=l(),v=u("FID"),m=function(e){e.startTimen.latency){if(t)t.entries.push(e),t.latency=Math.max(t.latency,e.duration);else{var i={id:e.interactionId,latency:e.duration,entries:[e]};x[i.id]=i,q.push(i)}q.sort((function(e,n){return n.latency-e.latency})),q.splice(10).forEach((function(e){delete x[e.id]}))}}(e)}));var n,a=(n=Math.min(q.length-1,Math.floor(R()/50)),q[n]);a&&a.latency!==i.value&&(i.value=a.latency,i.entries=a.entries,t())},r=f("event",a,{durationThreshold:40});t=d(e,i,n),r&&(s((function(){a(r.takeRecords()),i.value<0&&R()>0&&(i.value=0,i.entries=[]),t(!0)})),o((function(){q=[],N=B(),i=u("INP"),t=d(e,i,n)})))},H={},O=function(e,n){var t,i=l(),a=u("LCP"),r=function(e){var n=e[e.length-1];if(n){var r=n.startTime;rperformance.now())return;i.entries=[e],a(!0)}},"complete"===document.readyState?setTimeout(t,0):addEventListener("load",(function(){return setTimeout(t,0)})),o((function(t){i=u("TTFB"),a=d(e,i,n),i.value=performance.now()-t.timeStamp,a(!0)}))};export{T as getCLS,h as getFCP,I as getFID,A as getINP,O as getLCP,_ as getTFB,T as onCLS,h as onFCP,I as onFID,A as onINP,O as onLCP,_ as onTTFB}; +var e,t,n,r,i,a=function(){return window.performance&&performance.getEntriesByType&&performance.getEntriesByType("navigation")[0]},o=function(e){if("loading"===document.readyState)return"loading";var t=a();if(t){if(e(t||100)-1)return n||i;if(n=n?i+">"+n:i,r.id)break;e=r.parentNode}}catch(e){}return n},s=-1,f=function(){return s},d=function(e){addEventListener("pageshow",(function(t){t.persisted&&(s=t.timeStamp,e(t))}),!0)},l=function(){var e=a();return e&&e.activationStart||0},m=function(e,t){var n=a(),r="navigate";return f()>=0?r="back-forward-cache":n&&(r=document.prerendering||l()>0?"prerender":document.wasDiscarded?"restore":n.type.replace(/_/g,"-")),{name:e,value:void 0===t?-1:t,rating:"good",delta:0,entries:[],id:"v3-".concat(Date.now(),"-").concat(Math.floor(8999999999999*Math.random())+1e12),navigationType:r}},v=function(e,t,n){try{if(PerformanceObserver.supportedEntryTypes.includes(e)){var r=new PerformanceObserver((function(e){Promise.resolve().then((function(){t(e.getEntries())}))}));return r.observe(Object.assign({type:e,buffered:!0},n||{})),r}}catch(e){}},p=function(e,t,n,r){var i,a;return function(o){t.value>=0&&(o||r)&&((a=t.value-(i||0))||void 0===i)&&(i=t.value,t.delta=a,t.rating=function(e,t){return e>t[1]?"poor":e>t[0]?"needs-improvement":"good"}(t.value,n),e(t))}},h=function(e){requestAnimationFrame((function(){return requestAnimationFrame((function(){return e()}))}))},g=function(e){var t=function(t){"pagehide"!==t.type&&"hidden"!==document.visibilityState||e(t)};addEventListener("visibilitychange",t,!0),addEventListener("pagehide",t,!0)},T=function(e){var t=!1;return function(n){t||(e(n),t=!0)}},y=-1,E=function(){return"hidden"!==document.visibilityState||document.prerendering?1/0:0},S=function(e){"hidden"===document.visibilityState&&y>-1&&(y="visibilitychange"===e.type?e.timeStamp:0,C())},b=function(){addEventListener("visibilitychange",S,!0),addEventListener("prerenderingchange",S,!0)},C=function(){removeEventListener("visibilitychange",S,!0),removeEventListener("prerenderingchange",S,!0)},L=function(){return y<0&&(y=E(),b(),d((function(){setTimeout((function(){y=E(),b()}),0)}))),{get firstHiddenTime(){return y}}},w=function(e){document.prerendering?addEventListener("prerenderingchange",(function(){return e()}),!0):e()},M=[1800,3e3],x=function(e,t){t=t||{},w((function(){var n,r=L(),i=m("FCP"),a=v("paint",(function(e){e.forEach((function(e){"first-contentful-paint"===e.name&&(a.disconnect(),e.startTimer.value&&(r.value=i,r.entries=a,n())},u=v("layout-shift",o);u&&(n=p(e,r,A,t.reportAllChanges),g((function(){o(u.takeRecords()),n(!0)})),d((function(){i=0,r=m("CLS",0),n=p(e,r,A,t.reportAllChanges),h((function(){return n()}))})),setTimeout(n,0))})))}((function(t){!function(e){if(e.entries.length){var t=e.entries.reduce((function(e,t){return e&&e.value>t.value?e:t}));if(t&&t.sources&&t.sources.length){var n=(r=t.sources).find((function(e){return e.node&&1===e.node.nodeType}))||r[0];if(n)return void(e.attribution={largestShiftTarget:c(n.node),largestShiftTime:t.startTime,largestShiftValue:t.value,largestShiftSource:n,largestShiftEntry:t,loadState:o(t.startTime)})}}var r;e.attribution={}}(t),e(t)}),t)},I=function(e,t){x((function(t){!function(e){if(e.entries.length){var t=a(),n=e.entries[e.entries.length-1];if(t){var r=t.activationStart||0,i=Math.max(0,t.responseStart-r);return void(e.attribution={timeToFirstByte:i,firstByteToFCP:e.value-i,loadState:o(e.entries[0].startTime),navigationEntry:t,fcpEntry:n})}}e.attribution={timeToFirstByte:0,firstByteToFCP:e.value,loadState:o(f())}}(t),e(t)}),t)},B={passive:!0,capture:!0},D=new Date,P=function(r,i){e||(e=i,t=r,n=new Date,N(removeEventListener),k())},k=function(){if(t>=0&&t1e12?new Date:performance.now())-e.timeStamp;"pointerdown"==e.type?function(e,t){var n=function(){P(e,t),i()},r=function(){i()},i=function(){removeEventListener("pointerup",n,B),removeEventListener("pointercancel",r,B)};addEventListener("pointerup",n,B),addEventListener("pointercancel",r,B)}(t,e):P(t,e)}},N=function(e){["mousedown","keydown","touchstart","pointerdown"].forEach((function(t){return e(t,R,B)}))},q=[100,300],H=function(n,i){i=i||{},w((function(){var a,o=L(),u=m("FID"),c=function(e){e.startTimet.latency){if(n)n.entries.push(e),n.latency=Math.max(n.latency,e.duration);else{var r={id:e.interactionId,latency:e.duration,entries:[e]};X[r.id]=r,W.push(r)}W.sort((function(e,t){return t.latency-e.latency})),W.splice(10).forEach((function(e){delete X[e.id]}))}},Z=function(e,t){t=t||{},w((function(){G();var n,r=m("INP"),i=function(e){e.forEach((function(e){(e.interactionId&&Y(e),"first-input"===e.entryType)&&(!W.some((function(t){return t.entries.some((function(t){return e.duration===t.duration&&e.startTime===t.startTime}))}))&&Y(e))}));var t,i=(t=Math.min(W.length-1,Math.floor(Q()/50)),W[t]);i&&i.latency!==r.value&&(r.value=i.latency,r.entries=i.entries,n())},a=v("event",i,{durationThreshold:t.durationThreshold||40});n=p(e,r,J,t.reportAllChanges),a&&(a.observe({type:"first-input",buffered:!0}),g((function(){i(a.takeRecords()),r.value<0&&Q()>0&&(r.value=0,r.entries=[]),n(!0)})),d((function(){W=[],K=z(),r=m("INP"),n=p(e,r,J,t.reportAllChanges)})))}))},$=function(e,t){Z((function(t){!function(e){if(e.entries.length){var t=e.entries.sort((function(e,t){return t.duration-e.duration||t.processingEnd-t.processingStart-(e.processingEnd-e.processingStart)}))[0];e.attribution={eventTarget:c(t.target),eventType:t.name,eventTime:t.startTime,eventEntry:t,loadState:o(t.startTime)}}else e.attribution={}}(t),e(t)}),t)},ee=[2500,4e3],te={},ne=function(e,t){!function(e,t){t=t||{},w((function(){var n,r=L(),i=m("LCP"),a=function(e){var t=e[e.length-1];t&&t.startTimeperformance.now())return;n.value=Math.max(o-l(),0),n.entries=[i],r(!0),d((function(){n=m("TTFB",0),(r=p(e,n,re,t.reportAllChanges))(!0)}))}}))},oe=function(e,t){ae((function(t){!function(e){if(e.entries.length){var t=e.entries[0],n=t.activationStart||0,r=Math.max(t.domainLookupStart-n,0),i=Math.max(t.connectStart-n,0),a=Math.max(t.requestStart-n,0);e.attribution={waitingTime:r,dnsTime:i-r,connectionTime:a-i,requestTime:e.value-a,navigationEntry:t}}else e.attribution={waitingTime:0,dnsTime:0,connectionTime:0,requestTime:0}}(t),e(t)}),t)};export{A as CLSThresholds,M as FCPThresholds,q as FIDThresholds,J as INPThresholds,ee as LCPThresholds,re as TTFBThresholds,F as onCLS,I as onFCP,O as onFID,$ as onINP,ne as onLCP,oe as onTTFB}; diff --git a/src/options/options.html b/src/options/options.html index 79a00a8..2a83753 100644 --- a/src/options/options.html +++ b/src/options/options.html @@ -20,7 +20,12 @@
+
+