Skip to content

Commit a18f659

Browse files
authored
feat(browser)!: Remove FID web vital collection (#17076)
This PR removes the FID web vital collection logic from the browser SDK. This is a behaviour breaking change and should not be backported to `v9`. For reasons see #16560 but the TLDR is that FID has long been deprecated and replaced by INP. Added a note to the changelog with possible implications on the product. Also thought of a minor edge case where the removal could have an effect on SDK code: If a filtering decision in `beforeSend` depends on the presence of the FID measurement. A very niche case IMHO but probably good to mention anyway. closes #16560
1 parent f807802 commit a18f659

File tree

22 files changed

+31
-475
lines changed

22 files changed

+31
-475
lines changed

MIGRATION.md

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,3 +70,20 @@ Additionally, we hold ourselves accountable to any security issues, meaning that
7070

7171
Note, that it is decided on a case-per-case basis, what gets backported or not.
7272
If you need a fix or feature in a previous version of the SDK, please reach out via a GitHub Issue.
73+
74+
## 3. Behaviour Changes
75+
76+
### Removal of First Input Delay (FID) Web Vital Reporting
77+
78+
Affected SDKs: All SDKs running in browser applications (`@sentry/browser`, `@sentry/react`, `@sentry/nextjs`, etc.)
79+
80+
In v10, the SDK stopped reporting the First Input Delay (FID) web vital.
81+
This was done because FID has been replaced by Interaction to Next Paint (INP) and is therefore no longer relevant for assessing and tracking a website's performance.
82+
For reference, FID has long been deprecated by Google's official `web-vitals` library and was eventually removed in version `5.0.0`.
83+
Sentry now follows Google's lead by also removing it.
84+
85+
The removal entails **no breaking API changes**. However, in rare cases, you might need to adjust some of your Sentry SDK and product setup:
86+
87+
- Remove any logic in `beforeSend` or other filtering/event processing logic that depends on FID or replace it with INP logic.
88+
- If you set up Sentry Alerts that depend on FID, be aware that these could trigger once you upgrade the SDK, due to a lack of new values.
89+
To replace them, adjust your alerts (or dashbaords) to use INP.

dev-packages/browser-integration-tests/suites/replay/customEvents/test.ts

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ import {
44
expectedClickBreadcrumb,
55
expectedCLSPerformanceSpan,
66
expectedFCPPerformanceSpan,
7-
expectedFIDPerformanceSpan,
87
expectedFPPerformanceSpan,
98
expectedLCPPerformanceSpan,
109
expectedMemoryPerformanceSpan,
@@ -56,7 +55,6 @@ sentryTest(
5655
expectedNavigationPerformanceSpan,
5756
expectedLCPPerformanceSpan,
5857
expectedCLSPerformanceSpan,
59-
expectedFIDPerformanceSpan,
6058
expectedFPPerformanceSpan,
6159
expectedFCPPerformanceSpan,
6260
expectedMemoryPerformanceSpan, // two memory spans - once per flush

dev-packages/browser-integration-tests/suites/replay/multiple-pages/test.ts

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ import {
44
expectedClickBreadcrumb,
55
expectedCLSPerformanceSpan,
66
expectedFCPPerformanceSpan,
7-
expectedFIDPerformanceSpan,
87
expectedFPPerformanceSpan,
98
expectedLCPPerformanceSpan,
109
expectedMemoryPerformanceSpan,
@@ -77,7 +76,6 @@ sentryTest(
7776
expectedNavigationPerformanceSpan,
7877
expectedLCPPerformanceSpan,
7978
expectedCLSPerformanceSpan,
80-
expectedFIDPerformanceSpan,
8179
expectedFPPerformanceSpan,
8280
expectedFCPPerformanceSpan,
8381
expectedMemoryPerformanceSpan, // two memory spans - once per flush
@@ -117,7 +115,6 @@ sentryTest(
117115
expectedReloadPerformanceSpan,
118116
expectedLCPPerformanceSpan,
119117
expectedCLSPerformanceSpan,
120-
expectedFIDPerformanceSpan,
121118
expectedFPPerformanceSpan,
122119
expectedFCPPerformanceSpan,
123120
expectedMemoryPerformanceSpan,
@@ -188,7 +185,6 @@ sentryTest(
188185
expectedNavigationPerformanceSpan,
189186
expectedLCPPerformanceSpan,
190187
expectedCLSPerformanceSpan,
191-
expectedFIDPerformanceSpan,
192188
expectedFPPerformanceSpan,
193189
expectedFCPPerformanceSpan,
194190
expectedMemoryPerformanceSpan,
@@ -326,7 +322,6 @@ sentryTest(
326322
expectedNavigationPerformanceSpan,
327323
expectedLCPPerformanceSpan,
328324
expectedCLSPerformanceSpan,
329-
expectedFIDPerformanceSpan,
330325
expectedFPPerformanceSpan,
331326
expectedFCPPerformanceSpan,
332327
expectedMemoryPerformanceSpan,

dev-packages/browser-integration-tests/suites/tracing/metrics/web-vitals-fid/template.html

Lines changed: 0 additions & 9 deletions
This file was deleted.

dev-packages/browser-integration-tests/suites/tracing/metrics/web-vitals-fid/test.ts

Lines changed: 0 additions & 28 deletions
This file was deleted.

dev-packages/browser-integration-tests/utils/replayEventTemplates.ts

Lines changed: 0 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -148,19 +148,6 @@ export const expectedCLSPerformanceSpan = {
148148
},
149149
};
150150

151-
export const expectedFIDPerformanceSpan = {
152-
op: 'web-vital',
153-
description: 'first-input-delay',
154-
startTimestamp: expect.any(Number),
155-
endTimestamp: expect.any(Number),
156-
data: {
157-
value: expect.any(Number),
158-
rating: expect.any(String),
159-
size: expect.any(Number),
160-
nodeIds: expect.any(Array),
161-
},
162-
};
163-
164151
export const expectedINPPerformanceSpan = {
165152
op: 'web-vital',
166153
description: 'interaction-to-next-paint',

dev-packages/e2e-tests/test-applications/react-send-to-sentry/tests/fixtures/ReplayRecordingData.ts

Lines changed: 0 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -245,25 +245,6 @@ export const ReplayRecordingData = [
245245
},
246246
},
247247
},
248-
{
249-
type: 5,
250-
timestamp: expect.any(Number),
251-
data: {
252-
tag: 'performanceSpan',
253-
payload: {
254-
op: 'web-vital',
255-
description: 'first-input-delay',
256-
startTimestamp: expect.any(Number),
257-
endTimestamp: expect.any(Number),
258-
data: {
259-
value: expect.any(Number),
260-
size: expect.any(Number),
261-
rating: expect.any(String),
262-
nodeIds: [10],
263-
},
264-
},
265-
},
266-
},
267248
{
268249
type: 5,
269250
timestamp: expect.any(Number),

packages/browser-utils/src/index.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
export {
22
addPerformanceInstrumentationHandler,
33
addClsInstrumentationHandler,
4-
addFidInstrumentationHandler,
54
addTtfbInstrumentationHandler,
65
addLcpInstrumentationHandler,
76
addInpInstrumentationHandler,

packages/browser-utils/src/metrics/browserMetrics.ts

Lines changed: 0 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@ import { trackClsAsStandaloneSpan } from './cls';
1717
import {
1818
type PerformanceLongAnimationFrameTiming,
1919
addClsInstrumentationHandler,
20-
addFidInstrumentationHandler,
2120
addLcpInstrumentationHandler,
2221
addPerformanceInstrumentationHandler,
2322
addTtfbInstrumentationHandler,
@@ -103,13 +102,11 @@ export function startTrackingWebVitals({
103102
if (performance.mark) {
104103
WINDOW.performance.mark('sentry-tracing-init');
105104
}
106-
const fidCleanupCallback = _trackFID();
107105
const lcpCleanupCallback = recordLcpStandaloneSpans ? trackLcpAsStandaloneSpan(client) : _trackLCP();
108106
const ttfbCleanupCallback = _trackTtfb();
109107
const clsCleanupCallback = recordClsStandaloneSpans ? trackClsAsStandaloneSpan(client) : _trackCLS();
110108

111109
return (): void => {
112-
fidCleanupCallback();
113110
lcpCleanupCallback?.();
114111
ttfbCleanupCallback();
115112
clsCleanupCallback?.();
@@ -277,21 +274,6 @@ function _trackLCP(): () => void {
277274
}, true);
278275
}
279276

280-
/** Starts tracking the First Input Delay on the current page. */
281-
function _trackFID(): () => void {
282-
return addFidInstrumentationHandler(({ metric }) => {
283-
const entry = metric.entries[metric.entries.length - 1];
284-
if (!entry) {
285-
return;
286-
}
287-
288-
const timeOrigin = msToSec(browserPerformanceTimeOrigin() as number);
289-
const startTime = msToSec(entry.startTime);
290-
_measurements['fid'] = { value: metric.value, unit: 'millisecond' };
291-
_measurements['mark.fid'] = { value: timeOrigin + startTime, unit: 'second' };
292-
});
293-
}
294-
295277
function _trackTtfb(): () => void {
296278
return addTtfbInstrumentationHandler(({ metric }) => {
297279
const entry = metric.entries[metric.entries.length - 1];
@@ -415,21 +397,6 @@ export function addPerformanceEntries(span: Span, options: AddPerformanceEntries
415397
if (op === 'pageload') {
416398
_addTtfbRequestTimeToMeasurements(_measurements);
417399

418-
const fidMark = _measurements['mark.fid'];
419-
if (fidMark && _measurements['fid']) {
420-
// create span for FID
421-
startAndEndSpan(span, fidMark.value, fidMark.value + msToSec(_measurements['fid'].value), {
422-
name: 'first input delay',
423-
op: 'ui.action',
424-
attributes: {
425-
[SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.ui.browser.metrics',
426-
},
427-
});
428-
429-
// Delete mark.fid as we don't want it to be part of final payload
430-
delete _measurements['mark.fid'];
431-
}
432-
433400
// If CLS standalone spans are enabled, don't record CLS as a measurement
434401
if (!options.recordClsOnPageloadSpan) {
435402
delete _measurements.cls;

packages/browser-utils/src/metrics/instrument.ts

Lines changed: 6 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
import { debug, getFunctionName } from '@sentry/core';
22
import { DEBUG_BUILD } from '../debug-build';
33
import { onCLS } from './web-vitals/getCLS';
4-
import { onFID } from './web-vitals/getFID';
54
import { onINP } from './web-vitals/getINP';
65
import { onLCP } from './web-vitals/getLCP';
76
import { observe } from './web-vitals/lib/observe';
@@ -13,10 +12,11 @@ type InstrumentHandlerTypePerformanceObserver =
1312
| 'navigation'
1413
| 'paint'
1514
| 'resource'
16-
| 'first-input'
17-
| 'element';
15+
| 'element'
16+
// fist-input is still needed for INP
17+
| 'first-input';
1818

19-
type InstrumentHandlerTypeMetric = 'cls' | 'lcp' | 'fid' | 'ttfb' | 'inp';
19+
type InstrumentHandlerTypeMetric = 'cls' | 'lcp' | 'ttfb' | 'inp';
2020

2121
// We provide this here manually instead of relying on a global, as this is not available in non-browser environements
2222
// And we do not want to expose such types
@@ -51,7 +51,7 @@ interface Metric {
5151
/**
5252
* The name of the metric (in acronym form).
5353
*/
54-
name: 'CLS' | 'FCP' | 'FID' | 'INP' | 'LCP' | 'TTFB';
54+
name: 'CLS' | 'FCP' | 'INP' | 'LCP' | 'TTFB';
5555

5656
/**
5757
* The current value of the metric.
@@ -111,7 +111,6 @@ const handlers: { [key in InstrumentHandlerType]?: InstrumentHandlerCallback[] }
111111
const instrumented: { [key in InstrumentHandlerType]?: boolean } = {};
112112

113113
let _previousCls: Metric | undefined;
114-
let _previousFid: Metric | undefined;
115114
let _previousLcp: Metric | undefined;
116115
let _previousTtfb: Metric | undefined;
117116
let _previousInp: Metric | undefined;
@@ -145,15 +144,7 @@ export function addLcpInstrumentationHandler(
145144
}
146145

147146
/**
148-
* Add a callback that will be triggered when a FID metric is available.
149-
* Returns a cleanup callback which can be called to remove the instrumentation handler.
150-
*/
151-
export function addFidInstrumentationHandler(callback: (data: { metric: Metric }) => void): CleanupHandlerCallback {
152-
return addMetricObserver('fid', callback, instrumentFid, _previousFid);
153-
}
154-
155-
/**
156-
* Add a callback that will be triggered when a FID metric is available.
147+
* Add a callback that will be triggered when a TTFD metric is available.
157148
*/
158149
export function addTtfbInstrumentationHandler(callback: (data: { metric: Metric }) => void): CleanupHandlerCallback {
159150
return addMetricObserver('ttfb', callback, instrumentTtfb, _previousTtfb);
@@ -236,15 +227,6 @@ function instrumentCls(): StopListening {
236227
);
237228
}
238229

239-
function instrumentFid(): void {
240-
return onFID(metric => {
241-
triggerHandlers('fid', {
242-
metric,
243-
});
244-
_previousFid = metric;
245-
});
246-
}
247-
248230
function instrumentLcp(): StopListening {
249231
return onLCP(
250232
metric => {

0 commit comments

Comments
 (0)