Skip to content

Commit 974b664

Browse files
committed
feat(browser): Report browser.navigation.type on the pageload span
TTFB, FP and FCP are attributes of the pageload span rather than spans of their own, so unlike LCP, CLS and INP they had no navigation type to be read against. Report the type web-vitals measured TTFB and FCP on as an attribute of the pageload span.
1 parent 479d918 commit 974b664

5 files changed

Lines changed: 21 additions & 1 deletion

File tree

‎CHANGELOG.md‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
Work in this release was contributed by @psh4607, @thijsw, @trinitiwowka, @nehaprasad-dev, @JealousGx, @Jxxunnn, @eddie333016, @davidmurdoch, @yashschandra, @atharv-sys32, @AG0708, @birkskyum, @mkly, @mcbbugu, @suhailopensource, @zkasuran, @mohd-akram, @RealBhupesh, @halillusion, @psang39, @hafzism, @JosephDoUrden, @Tyagiquamar, @Andarist, @msnelling, and @oesnuj. Thank you for your contributions!
88

99
- feat(browser)!: `browser.navigation.type` on web vital and bfcache navigation spans now carries the navigation type exactly as web-vitals reports it. `bfcache` is now `back-forward-cache`, and a back/forward navigation that missed the bfcache (`back-forward`) or a discarded-tab restore (`restore`) is no longer folded into `navigate`. Update any dashboards or alerts filtering on `bfcache`.
10+
- feat(browser): The pageload span now carries `browser.navigation.type`, the navigation type web-vitals reported TTFB and FCP for. Those vitals, and FP, are attributes of the pageload span rather than spans of their own, so until now there was no navigation type to read them against.
1011
- feat(core): Add `createFetchIntegration`, the shared implementation behind the global-`fetch` integrations in `@sentry/bun`, `@sentry/cloudflare`, `@sentry/deno` and `@sentry/vercel-edge`. Those four packages carried four copies of it; they now share one. Two changes come out of that:
1112
- All four gain a `tracePropagation` option (default `true`). Turn it off to stop injecting `sentry-trace` and `baggage` without also turning off spans. To scope propagation to specific URLs, keep using `tracePropagationTargets` in the client options.
1213
- Integration options now follow the client. Previously a second `Sentry.init()` in the same process silently reused the options of the first one.

‎dev-packages/browser-integration-tests/suites/tracing/browserTracingIntegration/pageload-streamed/test.ts‎

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import {
88
SEMANTIC_ATTRIBUTE_SENTRY_SDK_INTEGRATIONS,
99
} from '@sentry/core';
1010
import {
11+
BROWSER_NAVIGATION_TYPE,
1112
SENTRY_SEGMENT_NAME_SOURCE,
1213
SENTRY_SEGMENT_ID,
1314
SENTRY_SEGMENT_NAME,
@@ -125,6 +126,10 @@ sentryTest(
125126
type: expect.stringMatching(/^(integer)|(double)$/),
126127
value: expect.any(Number),
127128
},
129+
[BROWSER_NAVIGATION_TYPE]: {
130+
type: 'string',
131+
value: 'navigate',
132+
},
128133
}),
129134
'sentry.idle_span_finish_reason': {
130135
type: 'string',

‎packages/browser-utils/src/web-vitals/tracking.ts‎

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
import type { Client, Measurements, Span } from '@sentry/core';
22
import { browserPerformanceTimeOrigin, debug, setMeasurement, spanToJSON } from '@sentry/core';
3-
import { SENTRY_OP } from '@sentry/conventions/attributes';
3+
import { BROWSER_NAVIGATION_TYPE, SENTRY_OP } from '@sentry/conventions/attributes';
44
import { DEBUG_BUILD } from '../debug-build';
55
import { htmlTreeAsString } from '../htmlTreeAsString';
6+
import type { MetricNavigationType } from '../instrumentation/performanceObserver';
67
import {
78
addClsInstrumentationHandler,
89
addFcpInstrumentationHandler,
@@ -17,6 +18,7 @@ import { getActivationStart, getNavigationEntry, getVisibilityWatcher } from './
1718
let _measurements: Measurements = {};
1819
let _lcpEntry: LargestContentfulPaint | undefined;
1920
let _clsEntry: LayoutShift | undefined;
21+
let _navigationType: MetricNavigationType | undefined;
2022

2123
interface StartTrackingWebVitalsOptions {
2224
trackCls: boolean;
@@ -83,6 +85,8 @@ function _trackLCP(): () => void {
8385

8486
function _trackTtfb(): () => void {
8587
return addTtfbInstrumentationHandler(({ metric }) => {
88+
_navigationType = metric.navigationType;
89+
8690
const entry = metric.entries[metric.entries.length - 1];
8791
if (!entry) {
8892
return;
@@ -95,6 +99,7 @@ function _trackTtfb(): () => void {
9599
/** Starts tracking the First Contentful Paint on the current page. */
96100
function _trackFcp(): () => void {
97101
return addFcpInstrumentationHandler(({ metric }) => {
102+
_navigationType = metric.navigationType;
98103
_measurements['fcp'] = { value: metric.value, unit: 'millisecond' };
99104
});
100105
}
@@ -201,6 +206,12 @@ export function addWebVitalsToSpan(span: Span, options: AddWebVitalsToSpanOption
201206
_setWebVitalAttributes(span, options);
202207
}
203208

209+
// TTFB, FP and FCP are attributes of this span rather than spans of their own, so the navigation
210+
// type they were measured on is reported here for them to be read against.
211+
if (_navigationType) {
212+
span.setAttribute(BROWSER_NAVIGATION_TYPE, _navigationType);
213+
}
214+
204215
// Set timeOrigin which denotes the timestamp which to base the LCP/FCP/FP/TTFB measurements on
205216
span.setAttribute(spanStreamingEnabled ? 'browser.performance.time_origin' : 'performance.timeOrigin', timeOrigin);
206217

@@ -222,6 +233,7 @@ export function addWebVitalsToSpan(span: Span, options: AddWebVitalsToSpanOption
222233
function resetWebVitalState(): void {
223234
_lcpEntry = undefined;
224235
_clsEntry = undefined;
236+
_navigationType = undefined;
225237
_measurements = {};
226238
}
227239

‎packages/browser-utils/test/web-vitals/tracking-fp-fcp-prerender.test.ts‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -124,5 +124,6 @@ describe('startTrackingWebVitals', () => {
124124

125125
expect(spanToJSON(pageloadSpan).attributes['browser.web_vital.fp.value']).toBe(12);
126126
expect(spanToJSON(pageloadSpan).attributes['browser.web_vital.fcp.value']).toBe(18);
127+
expect(spanToJSON(pageloadSpan).attributes['browser.navigation.type']).toBe('prerender');
127128
});
128129
});

‎packages/browser-utils/test/web-vitals/tracking-fp-fcp.test.ts‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,5 +90,6 @@ describe('startTrackingWebVitals', () => {
9090

9191
expect(spanToJSON(pageloadSpan).attributes['browser.web_vital.fp.value']).toBe(12);
9292
expect(spanToJSON(pageloadSpan).attributes['browser.web_vital.fcp.value']).toBe(18);
93+
expect(spanToJSON(pageloadSpan).attributes['browser.navigation.type']).toBe('navigate');
9394
});
9495
});

0 commit comments

Comments
 (0)