From 726b17543222041f8dc17df49b56f256c583e365 Mon Sep 17 00:00:00 2001 From: Alberto Leal Date: Fri, 30 Oct 2020 04:25:05 -0400 Subject: [PATCH 1/6] fix(web-vitals): Adjust some web vitals to be relative to fetchStart --- packages/tracing/src/browser/metrics.ts | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/packages/tracing/src/browser/metrics.ts b/packages/tracing/src/browser/metrics.ts index 00554fd02f6d..330df8dd5274 100644 --- a/packages/tracing/src/browser/metrics.ts +++ b/packages/tracing/src/browser/metrics.ts @@ -134,6 +134,28 @@ export class MetricsInstrumentation { // Measurements are only available for pageload transactions if (transaction.op === 'pageload') { + // normalize applicable web vital values to be relative to transaction.startTimestamp + + const timeOrigin = msToSec(performance.timeOrigin); + + ['fcp', 'fp', 'lcp', 'ttfb'].forEach(name => { + if (!this._measurements[name]) { + return; + } + + const oldValue = this._measurements[name].value; + const measurementTimestamp = timeOrigin + msToSec(oldValue); + // normalizedValue should be in milliseconds + const normalizedValue = (measurementTimestamp - transaction.startTimestamp) * 1000; + + const delta = normalizedValue - oldValue; + logger.log( + `[Measurements] Normalized ${name} from ${this._measurements[name].value} to ${normalizedValue} (${delta})`, + ); + + this._measurements[name] = { value: normalizedValue }; + }); + transaction.setMeasurements(this._measurements); } } @@ -253,6 +275,7 @@ function addNavigationSpans(transaction: Transaction, entry: Record addPerformanceNavigationTiming(transaction, entry, 'loadEvent', timeOrigin); addPerformanceNavigationTiming(transaction, entry, 'connect', timeOrigin); addPerformanceNavigationTiming(transaction, entry, 'secureConnection', timeOrigin, 'connectEnd'); + addPerformanceNavigationTiming(transaction, entry, 'fetch', timeOrigin, 'domainLookupStart'); addPerformanceNavigationTiming(transaction, entry, 'domainLookup', timeOrigin); addRequest(transaction, entry, timeOrigin); } From 886628ab6ee2fe97108c86aa7878588c9e3cec5a Mon Sep 17 00:00:00 2001 From: Alberto Leal Date: Fri, 30 Oct 2020 04:30:46 -0400 Subject: [PATCH 2/6] use getGlobalObject --- packages/tracing/src/browser/web-vitals/getTTFB.ts | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/packages/tracing/src/browser/web-vitals/getTTFB.ts b/packages/tracing/src/browser/web-vitals/getTTFB.ts index 43deb1268bbd..18f2aa0df45f 100644 --- a/packages/tracing/src/browser/web-vitals/getTTFB.ts +++ b/packages/tracing/src/browser/web-vitals/getTTFB.ts @@ -14,9 +14,13 @@ * limitations under the License. */ +import { getGlobalObject } from '@sentry/utils'; + import { initMetric } from './lib/initMetric'; import { ReportHandler } from './types'; +const global = getGlobalObject(); + interface NavigationEntryShim { // From `PerformanceNavigationTimingEntry`. entryType: string; @@ -80,7 +84,7 @@ const getNavigationEntryFromPerformanceTiming = (): PerformanceNavigationTiming // Note: browsers that do not support navigation entries will fall back to using performance.timing // (with the timestamps converted from epoch time to DOMHighResTimeStamp). // eslint-disable-next-line deprecation/deprecation - const timing = performance.timing; + const timing = global.performance.timing; const navigationEntry: NavigationEntryShim = { entryType: 'navigation', @@ -105,7 +109,7 @@ export const getTTFB = (onReport: ReportHandler): void => { try { // Use the NavigationTiming L2 entry if available. const navigationEntry = - performance.getEntriesByType('navigation')[0] || getNavigationEntryFromPerformanceTiming(); + global.performance.getEntriesByType('navigation')[0] || getNavigationEntryFromPerformanceTiming(); metric.value = metric.delta = (navigationEntry as PerformanceNavigationTiming).responseStart; From 63095df2f3b7d1cea57deac56fd71760183407e8 Mon Sep 17 00:00:00 2001 From: Alberto Leal Date: Fri, 30 Oct 2020 04:48:56 -0400 Subject: [PATCH 3/6] docs --- packages/tracing/src/browser/metrics.ts | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/packages/tracing/src/browser/metrics.ts b/packages/tracing/src/browser/metrics.ts index 330df8dd5274..08702bf6cd0b 100644 --- a/packages/tracing/src/browser/metrics.ts +++ b/packages/tracing/src/browser/metrics.ts @@ -139,10 +139,14 @@ export class MetricsInstrumentation { const timeOrigin = msToSec(performance.timeOrigin); ['fcp', 'fp', 'lcp', 'ttfb'].forEach(name => { - if (!this._measurements[name]) { + if (!this._measurements[name] || timeOrigin >= transaction.startTimestamp) { return; } + // The web vitals, fcp, fp, lcp, and ttfb, all measure relative to timeOrigin. + // Unfortunately, timeOrigin is not captured within the transaction span data, so these web vitals will need + // to be adjusted to be relative to transaction.startTimestamp. + const oldValue = this._measurements[name].value; const measurementTimestamp = timeOrigin + msToSec(oldValue); // normalizedValue should be in milliseconds From 8ba3e0ae12ea3e6b97034e109e65e2d38f7f27c2 Mon Sep 17 00:00:00 2001 From: Alberto Leal Date: Fri, 30 Oct 2020 05:03:10 -0400 Subject: [PATCH 4/6] create span for FID --- packages/tracing/src/browser/metrics.ts | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/packages/tracing/src/browser/metrics.ts b/packages/tracing/src/browser/metrics.ts index 08702bf6cd0b..48518bef9314 100644 --- a/packages/tracing/src/browser/metrics.ts +++ b/packages/tracing/src/browser/metrics.ts @@ -160,6 +160,17 @@ export class MetricsInstrumentation { this._measurements[name] = { value: normalizedValue }; }); + if (this._measurements['mark.fid'] && this._measurements['fid']) { + // create span for FID + + _startChild(transaction, { + description: 'first input delay', + endTimestamp: this._measurements['mark.fid'].value + msToSec(this._measurements['fid'].value), + op: 'web vitals', + startTimestamp: this._measurements['mark.fid'].value, + }); + } + transaction.setMeasurements(this._measurements); } } From 8d7ae28399f5d301a6cb87acecb54326566880bc Mon Sep 17 00:00:00 2001 From: Alberto Leal Date: Fri, 30 Oct 2020 16:34:15 -0400 Subject: [PATCH 5/6] rename op to web.vitals --- packages/tracing/src/browser/metrics.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/tracing/src/browser/metrics.ts b/packages/tracing/src/browser/metrics.ts index 48518bef9314..8ec3544b65c0 100644 --- a/packages/tracing/src/browser/metrics.ts +++ b/packages/tracing/src/browser/metrics.ts @@ -166,7 +166,7 @@ export class MetricsInstrumentation { _startChild(transaction, { description: 'first input delay', endTimestamp: this._measurements['mark.fid'].value + msToSec(this._measurements['fid'].value), - op: 'web vitals', + op: 'web.vitals', startTimestamp: this._measurements['mark.fid'].value, }); } From c7ea73f13231faae3cc73888fec9c9b96f7b5e07 Mon Sep 17 00:00:00 2001 From: Alberto Leal Date: Tue, 3 Nov 2020 03:43:14 -0500 Subject: [PATCH 6/6] Update packages/tracing/src/browser/metrics.ts Co-authored-by: Tony --- packages/tracing/src/browser/metrics.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/tracing/src/browser/metrics.ts b/packages/tracing/src/browser/metrics.ts index 8ec3544b65c0..849503e6e068 100644 --- a/packages/tracing/src/browser/metrics.ts +++ b/packages/tracing/src/browser/metrics.ts @@ -157,7 +157,7 @@ export class MetricsInstrumentation { `[Measurements] Normalized ${name} from ${this._measurements[name].value} to ${normalizedValue} (${delta})`, ); - this._measurements[name] = { value: normalizedValue }; + this._measurements[name].value = normalizedValue; }); if (this._measurements['mark.fid'] && this._measurements['fid']) {