diff --git a/src/package-lock.json b/src/package-lock.json index 99ca6792fe8..e7d6501da33 100644 --- a/src/package-lock.json +++ b/src/package-lock.json @@ -21,7 +21,7 @@ "run-script-os": "1.1.6", "showdown": "2.1.0", "smartypants": "0.2.2", - "web-vitals": "3.5.2", + "web-vitals": "4.0.0", "xml-js": "1.6.11" } }, @@ -1897,9 +1897,9 @@ } }, "node_modules/web-vitals": { - "version": "3.5.2", - "resolved": "https://registry.npmjs.org/web-vitals/-/web-vitals-3.5.2.tgz", - "integrity": "sha512-c0rhqNcHXRkY/ogGDJQxZ9Im9D19hDihbzSQJrsioex+KnFgmMzBiy57Z1EjkhX/+OjyBpclDCzz2ITtjokFmg==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/web-vitals/-/web-vitals-4.0.0.tgz", + "integrity": "sha512-8wQd4jkwFRwY5q3yAmHZAJ5MjnKR1vRACK+g2OEC8nUqi0WOxBrXfOxGNlJ+QtxzzSn/TkQO58wkW0coE68n0Q==", "dev": true }, "node_modules/web-worker": { @@ -3501,9 +3501,9 @@ "dev": true }, "web-vitals": { - "version": "3.5.2", - "resolved": "https://registry.npmjs.org/web-vitals/-/web-vitals-3.5.2.tgz", - "integrity": "sha512-c0rhqNcHXRkY/ogGDJQxZ9Im9D19hDihbzSQJrsioex+KnFgmMzBiy57Z1EjkhX/+OjyBpclDCzz2ITtjokFmg==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/web-vitals/-/web-vitals-4.0.0.tgz", + "integrity": "sha512-8wQd4jkwFRwY5q3yAmHZAJ5MjnKR1vRACK+g2OEC8nUqi0WOxBrXfOxGNlJ+QtxzzSn/TkQO58wkW0coE68n0Q==", "dev": true }, "web-worker": { diff --git a/src/package.json b/src/package.json index dbaef5e92fa..4401e33cb30 100644 --- a/src/package.json +++ b/src/package.json @@ -47,7 +47,7 @@ "run-script-os": "1.1.6", "showdown": "2.1.0", "smartypants": "0.2.2", - "web-vitals": "3.5.2", + "web-vitals": "4.0.0", "xml-js": "1.6.11" } } diff --git a/src/static/js/send-web-vitals.js b/src/static/js/send-web-vitals.js index 0e36f0152aa..a2b1795a24e 100644 --- a/src/static/js/send-web-vitals.js +++ b/src/static/js/send-web-vitals.js @@ -1,16 +1,7 @@ function sendWebVitals() { - function getLoafAttribution(attribution) { - if (!attribution) { - return {}; - } - - const entry = attribution.eventEntry; - if (!entry) { - return {}; - } - - if (!PerformanceObserver.supportedEntryTypes.includes('long-animation-frame')) { + function getLoafAttribution(attribution) { + if (!attribution?.longAnimationFrameEntries) { return {}; } @@ -18,42 +9,37 @@ function sendWebVitals() { debug_loaf_script_total_duration: 0 }; - const longAnimationFrames = performance.getEntriesByType('long-animation-frame'); - longAnimationFrames.filter(loaf => { - // LoAFs that intersect with the event. - return entry.startTime < (loaf.startTime + loaf.duration) && loaf.startTime < (entry.startTime + entry.duration); - }).forEach(loaf => { - const loafEndTime = loaf.startTime + loaf.duration; - loaf.scripts.forEach(script => { - if (script.duration <= loafAttribution.debug_loaf_script_total_duration) { - return; - } - loafAttribution = { - // Stats for the LoAF entry itself. - debug_loaf_entry_start_time: loaf.startTime, - debug_loaf_entry_end_time: loafEndTime, - debug_loaf_entry_work_duration: loaf.renderStart ? loaf.renderStart - loaf.startTime : loaf.duration, - debug_loaf_entry_render_duration: loaf.renderStart ? loafEndTime - loaf.renderStart : 0, - debug_loaf_entry_total_forced_style_and_layout_duration: loaf.scripts.reduce((sum, script) => sum + script.forcedStyleAndLayoutDuration, 0), - debug_loaf_entry_pre_layout_duration: loaf.styleAndLayoutStart ? loaf.styleAndLayoutStart - loaf.renderStart : 0, - debug_loaf_entry_style_and_layout_duration: loaf.styleAndLayoutStart ? loafEndTime - loaf.styleAndLayoutStart : 0, - - // Stats for the longest script in the LoAF entry. - debug_loaf_script_total_duration: script.duration, - debug_loaf_script_compile_duration: script.executionStart - script.startTime, - debug_loaf_script_exec_duration: script.startTime + script.duration - script.executionStart, - debug_loaf_script_source: script.sourceLocation || script.invoker || script.name, // TODO: remove after Chrome 123 - debug_loaf_script_type: script.invokerType || script.type, // TODO: remove `|| script.type` after Chrome 123 - // New in Chrome 122/123 (will be null until then) - debug_loaf_script_invoker: script.invoker, - debug_loaf_script_source_url: script.sourceURL, - debug_loaf_script_source_function_name: script.sourceFunctionName, - debug_loaf_script_source_char_position: script.sourceCharPosition, - - // LoAF metadata. - debug_loaf_meta_length: longAnimationFrames.length, - } - }); + // The last LoAF entry is usually the most relevant. + const loaf = attribution.longAnimationFrameEntries.at(-1) + const loafEndTime = loaf.startTime + loaf.duration; + loaf.scripts.forEach(script => { + if (script.duration <= loafAttribution.debug_loaf_script_total_duration) { + return; + } + loafAttribution = { + // Stats for the LoAF entry itself. + debug_loaf_entry_start_time: loaf.startTime, + debug_loaf_entry_end_time: loafEndTime, + debug_loaf_entry_work_duration: loaf.renderStart ? loaf.renderStart - loaf.startTime : loaf.duration, + debug_loaf_entry_render_duration: loaf.renderStart ? loafEndTime - loaf.renderStart : 0, + debug_loaf_entry_total_forced_style_and_layout_duration: loaf.scripts.reduce((sum, script) => sum + script.forcedStyleAndLayoutDuration, 0), + debug_loaf_entry_pre_layout_duration: loaf.styleAndLayoutStart ? loaf.styleAndLayoutStart - loaf.renderStart : 0, + debug_loaf_entry_style_and_layout_duration: loaf.styleAndLayoutStart ? loafEndTime - loaf.styleAndLayoutStart : 0, + + // Stats for the longest script in the LoAF entry. + debug_loaf_script_total_duration: script.duration, + debug_loaf_script_compile_duration: script.executionStart - script.startTime, + debug_loaf_script_exec_duration: script.startTime + script.duration - script.executionStart, + debug_loaf_script_forced_style_and_layout_duration: script.forcedStyleAndLayoutDuration, + debug_loaf_script_type: script.invokerType, + debug_loaf_script_invoker: script.invoker, + debug_loaf_script_source_url: script.sourceURL, + debug_loaf_script_source_function_name: script.sourceFunctionName, + debug_loaf_script_source_char_position: script.sourceCharPosition, + + // LoAF metadata. + debug_loaf_meta_length: attribution.longAnimationFrameEntries.length, + } }); if (!loafAttribution.debug_loaf_script_total_duration) { @@ -91,18 +77,15 @@ function sendWebVitals() { case 'INP': const loafAttribution = getLoafAttribution(attribution); overrides = { - debug_event: attribution.eventType, - debug_time: Math.round(attribution.eventTime), + debug_event: attribution.interactionType, + debug_time: Math.round(attribution.interactionTime), debug_load_state: attribution.loadState, - debug_target: attribution.eventTarget || '(not set)', + debug_target: attribution.interactionTarget || '(not set)', + debug_interaction_delay: Math.round(attribution.inputDelay), + debug_processing_duration: Math.round(attribution.processingDuration), + debug_presentation_delay: Math.round(attribution.presentationDelay), ...loafAttribution }; - if (!attribution.eventEntry) { - break; - } - overrides.debug_interaction_delay = Math.round(attribution.eventEntry.processingStart - attribution.eventEntry.startTime); - overrides.debug_processing_time = Math.round(attribution.eventEntry.processingEnd - attribution.eventEntry.processingStart); - overrides.debug_presentation_delay = Math.round(attribution.eventEntry.duration + attribution.eventEntry.startTime - attribution.eventEntry.processingEnd); break; case 'LCP': overrides = { diff --git a/src/templates/base.html b/src/templates/base.html index 35e064e56e3..351dfca4960 100644 --- a/src/templates/base.html +++ b/src/templates/base.html @@ -4,7 +4,6 @@ - {% block head %} {% block title %}The Web Almanac{% endblock %}