From e71ef472eee2c8d4f3eb0762933782b4d0b3d3ba Mon Sep 17 00:00:00 2001 From: Billy Vong Date: Tue, 14 Feb 2023 17:38:04 -0500 Subject: [PATCH 1/3] feat(replay): Change LCP calculation Fixes up calculating LCP timing based on `web-vitals`. Previously we were using the `duration` field on the PerformanceEntry, but it was always 0. Decided to change the `data.duration` field to `data.value` so that we do not break the frontend when trying to display this new field. --- .../src/util/createPerformanceEntries.ts | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/packages/replay/src/util/createPerformanceEntries.ts b/packages/replay/src/util/createPerformanceEntries.ts index f90dc7d0af32..62d1ca7cbecb 100644 --- a/packages/replay/src/util/createPerformanceEntries.ts +++ b/packages/replay/src/util/createPerformanceEntries.ts @@ -104,17 +104,27 @@ function createResourceEntry(entry: PerformanceResourceTiming) { // TODO: type definition! // eslint-disable-next-line @typescript-eslint/explicit-function-return-type function createLargestContentfulPaint(entry: PerformanceEntry & { size: number; element: Node }) { - const { duration, entryType, startTime, size } = entry; + const { entryType, startTime, size } = entry; - const start = getAbsoluteTime(startTime); + let startTimeOrNavigationActivation = 0; + + if (WINDOW.performance) { + const navEntry = WINDOW.performance.getEntriesByType('navigation')[0] as (PerformanceNavigationTiming & {activationStart: number}); + + // See https://github.com/GoogleChrome/web-vitals/blob/9f11c4c6578fb4c5ee6fa4e32b9d1d756475f135/src/lib/getActivationStart.ts#L21 + startTimeOrNavigationActivation = navEntry && navEntry.activationStart || 0; + } + + const start = getAbsoluteTime(startTimeOrNavigationActivation); + const value = Math.max(startTime - startTimeOrNavigationActivation, 0); return { type: entryType, name: entryType, start, - end: start + duration, + end: start + value, data: { - duration, + value, size, // Not sure why this errors, Node should be correct (Argument of type 'Node' is not assignable to parameter of type 'INode') // eslint-disable-next-line @typescript-eslint/no-explicit-any From 7f41c8c2eaeb14a978594b3474c30ac3ccf77149 Mon Sep 17 00:00:00 2001 From: Billy Vong Date: Wed, 15 Feb 2023 15:24:23 -0500 Subject: [PATCH 2/3] lint --- packages/replay/src/util/createPerformanceEntries.ts | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/packages/replay/src/util/createPerformanceEntries.ts b/packages/replay/src/util/createPerformanceEntries.ts index 62d1ca7cbecb..333a7fe5d809 100644 --- a/packages/replay/src/util/createPerformanceEntries.ts +++ b/packages/replay/src/util/createPerformanceEntries.ts @@ -109,10 +109,12 @@ function createLargestContentfulPaint(entry: PerformanceEntry & { size: number; let startTimeOrNavigationActivation = 0; if (WINDOW.performance) { - const navEntry = WINDOW.performance.getEntriesByType('navigation')[0] as (PerformanceNavigationTiming & {activationStart: number}); + const navEntry = WINDOW.performance.getEntriesByType('navigation')[0] as PerformanceNavigationTiming & { + activationStart: number; + }; // See https://github.com/GoogleChrome/web-vitals/blob/9f11c4c6578fb4c5ee6fa4e32b9d1d756475f135/src/lib/getActivationStart.ts#L21 - startTimeOrNavigationActivation = navEntry && navEntry.activationStart || 0; + startTimeOrNavigationActivation = (navEntry && navEntry.activationStart) || 0; } const start = getAbsoluteTime(startTimeOrNavigationActivation); From a12b0feecfd739937936af57d3715280644355b2 Mon Sep 17 00:00:00 2001 From: Billy Vong Date: Wed, 15 Feb 2023 17:26:10 -0500 Subject: [PATCH 3/3] fix test --- packages/integration-tests/utils/replayEventTemplates.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/integration-tests/utils/replayEventTemplates.ts b/packages/integration-tests/utils/replayEventTemplates.ts index 6a86ef8f45c7..17aa903a0391 100644 --- a/packages/integration-tests/utils/replayEventTemplates.ts +++ b/packages/integration-tests/utils/replayEventTemplates.ts @@ -91,7 +91,7 @@ export const expectedLCPPerformanceSpan = { startTimestamp: expect.any(Number), endTimestamp: expect.any(Number), data: { - duration: expect.any(Number), + value: expect.any(Number), nodeId: expect.any(Number), size: expect.any(Number), },