Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions src/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion src/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@
"run-script-os": "1.1.6",
"showdown": "2.1.0",
"smartypants": "0.2.2",
"web-vitals": "4.2.4",
"web-vitals": "5.0.0",
"xml-js": "1.6.11"
}
}
81 changes: 18 additions & 63 deletions src/static/js/send-web-vitals.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,64 +2,14 @@

function sendWebVitals() {

function getLoafAttribution(attribution) {
const loafEntriesLength = attribution?.longAnimationFrameEntries?.length || 0;
if (loafEntriesLength === 0) {
return {};
}

let loafAttribution = {
debug_loaf_script_total_duration: 0
};

// 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: loafEntriesLength,
}
});

if (!loafAttribution.debug_loaf_script_total_duration) {
return {};
}

// The LoAF script with the single longest total duration.
return Object.fromEntries(Object.entries(loafAttribution).map(([k, v]) => {
// Convert all floats to ints.
return [k, typeof v == 'number' ? Math.floor(v) : v];
}));
}

function sendWebVitalsGAEvents({name, delta, value, id, attribution, navigationType}) {

let overrides = {};

function roundIfNotNull(x) {
return x != null ? Math.round(x) : null;
}

switch (name) {
case 'CLS':
overrides = {
Expand All @@ -76,18 +26,24 @@ function sendWebVitals() {
debug_target: attribution.loadState || '(not set)',
};
break;
case 'FID':
case 'INP': {
const loafAttribution = getLoafAttribution(attribution);
overrides = {
debug_event: attribution.interactionType,
debug_time: Math.round(attribution.interactionTime),
debug_time: roundIfNotNull(attribution.interactionTime),
debug_load_state: attribution.loadState,
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
debug_interaction_delay: roundIfNotNull(attribution.inputDelay),
debug_processing_duration: roundIfNotNull(attribution.processingDuration),
debug_presentation_delay: roundIfNotNull(attribution.presentationDelay),
debug_totalPaintDuration: roundIfNotNull(attribution.totalPaintDuration),
debug_totalScriptDuration: roundIfNotNull(attribution.totalScriptDuration),
debug_totalStyleAndLayoutDuration: roundIfNotNull(attribution.totalStyleAndLayoutDuration),
debug_totalUnattributedDuration: roundIfNotNull(attribution.totalUnattributedDuration),
debug_longestScriptIntersectingDuration: roundIfNotNull(attribution.longestScript?.intersectingDuration),
debug_longestScriptSubPart: attribution.longestScript?.subpart || null,
debug_longestScriptInvoker: attribution.longestScript?.entry.invoker || null,
debug_longestScriptInvokerType: attribution.longestScript?.entry.invokerType || null,
debug_longestScriptName: attribution.longestScript?.entry.name || null,
};
break;
}
Expand All @@ -98,7 +54,7 @@ function sendWebVitals() {
debug_resource_load_delay: attribution.resourceLoadDelay,
debug_resource_load_time: attribution.resourceLoadTime,
debug_element_render_delay: attribution.elementRenderDelay,
debug_target: attribution.element || '(not set)',
debug_target: attribution.target || '(not set)',
};
break;
case 'TTFB':
Expand Down Expand Up @@ -163,7 +119,6 @@ function sendWebVitals() {
webVitals.onLCP(sendWebVitalsGAEvents);
webVitals.onCLS(sendWebVitalsGAEvents);
webVitals.onTTFB(sendWebVitalsGAEvents);
webVitals.onFID(sendWebVitalsGAEvents);
webVitals.onINP(sendWebVitalsGAEvents);
} else {
console.error('Web Vitals is not loaded!!');
Expand Down
Loading