diff --git a/MIGRATION.md b/MIGRATION.md
index 63b9b67e1f9d..3a21e9288656 100644
--- a/MIGRATION.md
+++ b/MIGRATION.md
@@ -70,3 +70,20 @@ Additionally, we hold ourselves accountable to any security issues, meaning that
Note, that it is decided on a case-per-case basis, what gets backported or not.
If you need a fix or feature in a previous version of the SDK, please reach out via a GitHub Issue.
+
+## 3. Behaviour Changes
+
+### Removal of First Input Delay (FID) Web Vital Reporting
+
+Affected SDKs: All SDKs running in browser applications (`@sentry/browser`, `@sentry/react`, `@sentry/nextjs`, etc.)
+
+In v10, the SDK stopped reporting the First Input Delay (FID) web vital.
+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.
+For reference, FID has long been deprecated by Google's official `web-vitals` library and was eventually removed in version `5.0.0`.
+Sentry now follows Google's lead by also removing it.
+
+The removal entails **no breaking API changes**. However, in rare cases, you might need to adjust some of your Sentry SDK and product setup:
+
+- Remove any logic in `beforeSend` or other filtering/event processing logic that depends on FID or replace it with INP logic.
+- 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.
+ To replace them, adjust your alerts (or dashbaords) to use INP.
diff --git a/dev-packages/browser-integration-tests/suites/replay/customEvents/test.ts b/dev-packages/browser-integration-tests/suites/replay/customEvents/test.ts
index 336e09a331e1..a83f6e9fa5ce 100644
--- a/dev-packages/browser-integration-tests/suites/replay/customEvents/test.ts
+++ b/dev-packages/browser-integration-tests/suites/replay/customEvents/test.ts
@@ -4,7 +4,6 @@ import {
expectedClickBreadcrumb,
expectedCLSPerformanceSpan,
expectedFCPPerformanceSpan,
- expectedFIDPerformanceSpan,
expectedFPPerformanceSpan,
expectedLCPPerformanceSpan,
expectedMemoryPerformanceSpan,
@@ -56,7 +55,6 @@ sentryTest(
expectedNavigationPerformanceSpan,
expectedLCPPerformanceSpan,
expectedCLSPerformanceSpan,
- expectedFIDPerformanceSpan,
expectedFPPerformanceSpan,
expectedFCPPerformanceSpan,
expectedMemoryPerformanceSpan, // two memory spans - once per flush
diff --git a/dev-packages/browser-integration-tests/suites/replay/multiple-pages/test.ts b/dev-packages/browser-integration-tests/suites/replay/multiple-pages/test.ts
index 2c059bb226f4..14d6ce3783b1 100644
--- a/dev-packages/browser-integration-tests/suites/replay/multiple-pages/test.ts
+++ b/dev-packages/browser-integration-tests/suites/replay/multiple-pages/test.ts
@@ -4,7 +4,6 @@ import {
expectedClickBreadcrumb,
expectedCLSPerformanceSpan,
expectedFCPPerformanceSpan,
- expectedFIDPerformanceSpan,
expectedFPPerformanceSpan,
expectedLCPPerformanceSpan,
expectedMemoryPerformanceSpan,
@@ -77,7 +76,6 @@ sentryTest(
expectedNavigationPerformanceSpan,
expectedLCPPerformanceSpan,
expectedCLSPerformanceSpan,
- expectedFIDPerformanceSpan,
expectedFPPerformanceSpan,
expectedFCPPerformanceSpan,
expectedMemoryPerformanceSpan, // two memory spans - once per flush
@@ -117,7 +115,6 @@ sentryTest(
expectedReloadPerformanceSpan,
expectedLCPPerformanceSpan,
expectedCLSPerformanceSpan,
- expectedFIDPerformanceSpan,
expectedFPPerformanceSpan,
expectedFCPPerformanceSpan,
expectedMemoryPerformanceSpan,
@@ -188,7 +185,6 @@ sentryTest(
expectedNavigationPerformanceSpan,
expectedLCPPerformanceSpan,
expectedCLSPerformanceSpan,
- expectedFIDPerformanceSpan,
expectedFPPerformanceSpan,
expectedFCPPerformanceSpan,
expectedMemoryPerformanceSpan,
@@ -326,7 +322,6 @@ sentryTest(
expectedNavigationPerformanceSpan,
expectedLCPPerformanceSpan,
expectedCLSPerformanceSpan,
- expectedFIDPerformanceSpan,
expectedFPPerformanceSpan,
expectedFCPPerformanceSpan,
expectedMemoryPerformanceSpan,
diff --git a/dev-packages/browser-integration-tests/suites/tracing/metrics/web-vitals-fid/template.html b/dev-packages/browser-integration-tests/suites/tracing/metrics/web-vitals-fid/template.html
deleted file mode 100644
index a3aeb9048dd8..000000000000
--- a/dev-packages/browser-integration-tests/suites/tracing/metrics/web-vitals-fid/template.html
+++ /dev/null
@@ -1,9 +0,0 @@
-
-
-
-
-
-
-
-
-
diff --git a/dev-packages/browser-integration-tests/suites/tracing/metrics/web-vitals-fid/test.ts b/dev-packages/browser-integration-tests/suites/tracing/metrics/web-vitals-fid/test.ts
deleted file mode 100644
index a481364077a1..000000000000
--- a/dev-packages/browser-integration-tests/suites/tracing/metrics/web-vitals-fid/test.ts
+++ /dev/null
@@ -1,28 +0,0 @@
-import { expect } from '@playwright/test';
-import type { Event } from '@sentry/core';
-import { sentryTest } from '../../../../utils/fixtures';
-import { getFirstSentryEnvelopeRequest, shouldSkipTracingTest } from '../../../../utils/helpers';
-
-sentryTest('should capture a FID vital.', async ({ browserName, getLocalTestUrl, page }) => {
- // FID measurement is not generated on webkit
- if (shouldSkipTracingTest() || browserName === 'webkit') {
- sentryTest.skip();
- }
-
- const url = await getLocalTestUrl({ testDir: __dirname });
-
- await page.goto(url);
- // To trigger FID
- await page.locator('#fid-btn').click();
-
- const eventData = await getFirstSentryEnvelopeRequest(page);
-
- expect(eventData.measurements).toBeDefined();
- expect(eventData.measurements?.fid?.value).toBeDefined();
-
- const fidSpan = eventData.spans?.filter(({ description }) => description === 'first input delay')[0];
-
- expect(fidSpan).toBeDefined();
- expect(fidSpan?.op).toBe('ui.action');
- expect(fidSpan?.parent_span_id).toBe(eventData.contexts?.trace?.span_id);
-});
diff --git a/dev-packages/browser-integration-tests/utils/replayEventTemplates.ts b/dev-packages/browser-integration-tests/utils/replayEventTemplates.ts
index 56ff33f878fa..97787c2de26e 100644
--- a/dev-packages/browser-integration-tests/utils/replayEventTemplates.ts
+++ b/dev-packages/browser-integration-tests/utils/replayEventTemplates.ts
@@ -148,19 +148,6 @@ export const expectedCLSPerformanceSpan = {
},
};
-export const expectedFIDPerformanceSpan = {
- op: 'web-vital',
- description: 'first-input-delay',
- startTimestamp: expect.any(Number),
- endTimestamp: expect.any(Number),
- data: {
- value: expect.any(Number),
- rating: expect.any(String),
- size: expect.any(Number),
- nodeIds: expect.any(Array),
- },
-};
-
export const expectedINPPerformanceSpan = {
op: 'web-vital',
description: 'interaction-to-next-paint',
diff --git a/dev-packages/e2e-tests/test-applications/react-send-to-sentry/tests/fixtures/ReplayRecordingData.ts b/dev-packages/e2e-tests/test-applications/react-send-to-sentry/tests/fixtures/ReplayRecordingData.ts
index 76abdb1fa6b5..c11fba897aff 100644
--- a/dev-packages/e2e-tests/test-applications/react-send-to-sentry/tests/fixtures/ReplayRecordingData.ts
+++ b/dev-packages/e2e-tests/test-applications/react-send-to-sentry/tests/fixtures/ReplayRecordingData.ts
@@ -245,25 +245,6 @@ export const ReplayRecordingData = [
},
},
},
- {
- type: 5,
- timestamp: expect.any(Number),
- data: {
- tag: 'performanceSpan',
- payload: {
- op: 'web-vital',
- description: 'first-input-delay',
- startTimestamp: expect.any(Number),
- endTimestamp: expect.any(Number),
- data: {
- value: expect.any(Number),
- size: expect.any(Number),
- rating: expect.any(String),
- nodeIds: [10],
- },
- },
- },
- },
{
type: 5,
timestamp: expect.any(Number),
diff --git a/packages/browser-utils/src/index.ts b/packages/browser-utils/src/index.ts
index 0a2d9e85ade9..bf6605f3f399 100644
--- a/packages/browser-utils/src/index.ts
+++ b/packages/browser-utils/src/index.ts
@@ -1,7 +1,6 @@
export {
addPerformanceInstrumentationHandler,
addClsInstrumentationHandler,
- addFidInstrumentationHandler,
addTtfbInstrumentationHandler,
addLcpInstrumentationHandler,
addInpInstrumentationHandler,
diff --git a/packages/browser-utils/src/metrics/browserMetrics.ts b/packages/browser-utils/src/metrics/browserMetrics.ts
index d182c64030fa..870558ada39d 100644
--- a/packages/browser-utils/src/metrics/browserMetrics.ts
+++ b/packages/browser-utils/src/metrics/browserMetrics.ts
@@ -17,7 +17,6 @@ import { trackClsAsStandaloneSpan } from './cls';
import {
type PerformanceLongAnimationFrameTiming,
addClsInstrumentationHandler,
- addFidInstrumentationHandler,
addLcpInstrumentationHandler,
addPerformanceInstrumentationHandler,
addTtfbInstrumentationHandler,
@@ -103,13 +102,11 @@ export function startTrackingWebVitals({
if (performance.mark) {
WINDOW.performance.mark('sentry-tracing-init');
}
- const fidCleanupCallback = _trackFID();
const lcpCleanupCallback = recordLcpStandaloneSpans ? trackLcpAsStandaloneSpan(client) : _trackLCP();
const ttfbCleanupCallback = _trackTtfb();
const clsCleanupCallback = recordClsStandaloneSpans ? trackClsAsStandaloneSpan(client) : _trackCLS();
return (): void => {
- fidCleanupCallback();
lcpCleanupCallback?.();
ttfbCleanupCallback();
clsCleanupCallback?.();
@@ -277,21 +274,6 @@ function _trackLCP(): () => void {
}, true);
}
-/** Starts tracking the First Input Delay on the current page. */
-function _trackFID(): () => void {
- return addFidInstrumentationHandler(({ metric }) => {
- const entry = metric.entries[metric.entries.length - 1];
- if (!entry) {
- return;
- }
-
- const timeOrigin = msToSec(browserPerformanceTimeOrigin() as number);
- const startTime = msToSec(entry.startTime);
- _measurements['fid'] = { value: metric.value, unit: 'millisecond' };
- _measurements['mark.fid'] = { value: timeOrigin + startTime, unit: 'second' };
- });
-}
-
function _trackTtfb(): () => void {
return addTtfbInstrumentationHandler(({ metric }) => {
const entry = metric.entries[metric.entries.length - 1];
@@ -415,21 +397,6 @@ export function addPerformanceEntries(span: Span, options: AddPerformanceEntries
if (op === 'pageload') {
_addTtfbRequestTimeToMeasurements(_measurements);
- const fidMark = _measurements['mark.fid'];
- if (fidMark && _measurements['fid']) {
- // create span for FID
- startAndEndSpan(span, fidMark.value, fidMark.value + msToSec(_measurements['fid'].value), {
- name: 'first input delay',
- op: 'ui.action',
- attributes: {
- [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.ui.browser.metrics',
- },
- });
-
- // Delete mark.fid as we don't want it to be part of final payload
- delete _measurements['mark.fid'];
- }
-
// If CLS standalone spans are enabled, don't record CLS as a measurement
if (!options.recordClsOnPageloadSpan) {
delete _measurements.cls;
diff --git a/packages/browser-utils/src/metrics/instrument.ts b/packages/browser-utils/src/metrics/instrument.ts
index 23bbf57367d3..8017bd4c89e1 100644
--- a/packages/browser-utils/src/metrics/instrument.ts
+++ b/packages/browser-utils/src/metrics/instrument.ts
@@ -1,7 +1,6 @@
import { debug, getFunctionName } from '@sentry/core';
import { DEBUG_BUILD } from '../debug-build';
import { onCLS } from './web-vitals/getCLS';
-import { onFID } from './web-vitals/getFID';
import { onINP } from './web-vitals/getINP';
import { onLCP } from './web-vitals/getLCP';
import { observe } from './web-vitals/lib/observe';
@@ -13,10 +12,11 @@ type InstrumentHandlerTypePerformanceObserver =
| 'navigation'
| 'paint'
| 'resource'
- | 'first-input'
- | 'element';
+ | 'element'
+ // fist-input is still needed for INP
+ | 'first-input';
-type InstrumentHandlerTypeMetric = 'cls' | 'lcp' | 'fid' | 'ttfb' | 'inp';
+type InstrumentHandlerTypeMetric = 'cls' | 'lcp' | 'ttfb' | 'inp';
// We provide this here manually instead of relying on a global, as this is not available in non-browser environements
// And we do not want to expose such types
@@ -51,7 +51,7 @@ interface Metric {
/**
* The name of the metric (in acronym form).
*/
- name: 'CLS' | 'FCP' | 'FID' | 'INP' | 'LCP' | 'TTFB';
+ name: 'CLS' | 'FCP' | 'INP' | 'LCP' | 'TTFB';
/**
* The current value of the metric.
@@ -111,7 +111,6 @@ const handlers: { [key in InstrumentHandlerType]?: InstrumentHandlerCallback[] }
const instrumented: { [key in InstrumentHandlerType]?: boolean } = {};
let _previousCls: Metric | undefined;
-let _previousFid: Metric | undefined;
let _previousLcp: Metric | undefined;
let _previousTtfb: Metric | undefined;
let _previousInp: Metric | undefined;
@@ -145,15 +144,7 @@ export function addLcpInstrumentationHandler(
}
/**
- * Add a callback that will be triggered when a FID metric is available.
- * Returns a cleanup callback which can be called to remove the instrumentation handler.
- */
-export function addFidInstrumentationHandler(callback: (data: { metric: Metric }) => void): CleanupHandlerCallback {
- return addMetricObserver('fid', callback, instrumentFid, _previousFid);
-}
-
-/**
- * Add a callback that will be triggered when a FID metric is available.
+ * Add a callback that will be triggered when a TTFD metric is available.
*/
export function addTtfbInstrumentationHandler(callback: (data: { metric: Metric }) => void): CleanupHandlerCallback {
return addMetricObserver('ttfb', callback, instrumentTtfb, _previousTtfb);
@@ -236,15 +227,6 @@ function instrumentCls(): StopListening {
);
}
-function instrumentFid(): void {
- return onFID(metric => {
- triggerHandlers('fid', {
- metric,
- });
- _previousFid = metric;
- });
-}
-
function instrumentLcp(): StopListening {
return onLCP(
metric => {
diff --git a/packages/browser-utils/src/metrics/web-vitals/README.md b/packages/browser-utils/src/metrics/web-vitals/README.md
index 4f9d29e5f02f..a57937246cdd 100644
--- a/packages/browser-utils/src/metrics/web-vitals/README.md
+++ b/packages/browser-utils/src/metrics/web-vitals/README.md
@@ -27,6 +27,10 @@ web-vitals only report once per pageload.
## CHANGELOG
+https://github.com/getsentry/sentry-javascript/pull/17076
+
+- Removed FID-related code with v10 of the SDK
+
https://github.com/getsentry/sentry-javascript/pull/16492
- Bumped from Web Vitals 4.2.5 to 5.0.2
diff --git a/packages/browser-utils/src/metrics/web-vitals/getFID.ts b/packages/browser-utils/src/metrics/web-vitals/getFID.ts
deleted file mode 100644
index b549f4c07c7c..000000000000
--- a/packages/browser-utils/src/metrics/web-vitals/getFID.ts
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
- * Copyright 2020 Google LLC
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * https://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * // Sentry: web-vitals removed FID reporting from v5. We're keeping it around
- * for the time being.
- * // TODO(v10): Remove FID reporting!
- */
-
-import { bindReporter } from './lib/bindReporter';
-import { getVisibilityWatcher } from './lib/getVisibilityWatcher';
-import { initMetric } from './lib/initMetric';
-import { observe } from './lib/observe';
-import { onHidden } from './lib/onHidden';
-import { runOnce } from './lib/runOnce';
-import { whenActivated } from './lib/whenActivated';
-import type { FIDMetric, MetricRatingThresholds, ReportOpts } from './types';
-
-/** Thresholds for FID. See https://web.dev/articles/fid#what_is_a_good_fid_score */
-export const FIDThresholds: MetricRatingThresholds = [100, 300];
-
-/**
- * Calculates the [FID](https://web.dev/articles/fid) value for the current page and
- * calls the `callback` function once the value is ready, along with the
- * relevant `first-input` performance entry used to determine the value. The
- * reported value is a `DOMHighResTimeStamp`.
- *
- * _**Important:** since FID is only reported after the user interacts with the
- * page, it's possible that it will not be reported for some page loads._
- */
-export const onFID = (onReport: (metric: FIDMetric) => void, opts: ReportOpts = {}) => {
- whenActivated(() => {
- const visibilityWatcher = getVisibilityWatcher();
- const metric = initMetric('FID');
- // eslint-disable-next-line prefer-const
- let report: ReturnType;
-
- const handleEntry = (entry: PerformanceEventTiming): void => {
- // Only report if the page wasn't hidden prior to the first input.
- if (entry.startTime < visibilityWatcher.firstHiddenTime) {
- metric.value = entry.processingStart - entry.startTime;
- metric.entries.push(entry);
- report(true);
- }
- };
-
- const handleEntries = (entries: FIDMetric['entries']) => {
- (entries as PerformanceEventTiming[]).forEach(handleEntry);
- };
-
- const po = observe('first-input', handleEntries);
-
- report = bindReporter(onReport, metric, FIDThresholds, opts.reportAllChanges);
-
- if (po) {
- // sentry: TODO: Figure out if we can use new whinIdleOrHidden insteard of onHidden
- onHidden(
- runOnce(() => {
- handleEntries(po.takeRecords() as FIDMetric['entries']);
- po.disconnect();
- }),
- );
- }
- });
-};
diff --git a/packages/browser-utils/src/metrics/web-vitals/lib/interactions.ts b/packages/browser-utils/src/metrics/web-vitals/lib/interactions.ts
deleted file mode 100644
index 69ca920ddb67..000000000000
--- a/packages/browser-utils/src/metrics/web-vitals/lib/interactions.ts
+++ /dev/null
@@ -1,136 +0,0 @@
-/*
- * Copyright 2024 Google LLC
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * https://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-import { getInteractionCount } from './polyfills/interactionCountPolyfill';
-
-interface Interaction {
- id: number;
- latency: number;
- entries: PerformanceEventTiming[];
-}
-
-interface EntryPreProcessingHook {
- (entry: PerformanceEventTiming): void;
-}
-
-// A list of longest interactions on the page (by latency) sorted so the
-// longest one is first. The list is at most MAX_INTERACTIONS_TO_CONSIDER long.
-export const longestInteractionList: Interaction[] = [];
-
-// A mapping of longest interactions by their interaction ID.
-// This is used for faster lookup.
-export const longestInteractionMap: Map = new Map();
-
-// The default `durationThreshold` used across this library for observing
-// `event` entries via PerformanceObserver.
-export const DEFAULT_DURATION_THRESHOLD = 40;
-
-// Used to store the interaction count after a bfcache restore, since p98
-// interaction latencies should only consider the current navigation.
-let prevInteractionCount = 0;
-
-/**
- * Returns the interaction count since the last bfcache restore (or for the
- * full page lifecycle if there were no bfcache restores).
- */
-const getInteractionCountForNavigation = () => {
- return getInteractionCount() - prevInteractionCount;
-};
-
-export const resetInteractions = () => {
- prevInteractionCount = getInteractionCount();
- longestInteractionList.length = 0;
- longestInteractionMap.clear();
-};
-
-/**
- * Returns the estimated p98 longest interaction based on the stored
- * interaction candidates and the interaction count for the current page.
- */
-export const estimateP98LongestInteraction = () => {
- const candidateInteractionIndex = Math.min(
- longestInteractionList.length - 1,
- Math.floor(getInteractionCountForNavigation() / 50),
- );
-
- return longestInteractionList[candidateInteractionIndex];
-};
-
-// To prevent unnecessary memory usage on pages with lots of interactions,
-// store at most 10 of the longest interactions to consider as INP candidates.
-const MAX_INTERACTIONS_TO_CONSIDER = 10;
-
-/**
- * A list of callback functions to run before each entry is processed.
- * Exposing this list allows the attribution build to hook into the
- * entry processing pipeline.
- */
-export const entryPreProcessingCallbacks: EntryPreProcessingHook[] = [];
-
-/**
- * Takes a performance entry and adds it to the list of worst interactions
- * if its duration is long enough to make it among the worst. If the
- * entry is part of an existing interaction, it is merged and the latency
- * and entries list is updated as needed.
- */
-export const processInteractionEntry = (entry: PerformanceEventTiming) => {
- entryPreProcessingCallbacks.forEach(cb => cb(entry));
-
- // Skip further processing for entries that cannot be INP candidates.
- if (!(entry.interactionId || entry.entryType === 'first-input')) return;
-
- // The least-long of the 10 longest interactions.
- const minLongestInteraction = longestInteractionList[longestInteractionList.length - 1];
-
- const existingInteraction = longestInteractionMap.get(entry.interactionId!);
-
- // Only process the entry if it's possibly one of the ten longest,
- // or if it's part of an existing interaction.
- if (
- existingInteraction ||
- longestInteractionList.length < MAX_INTERACTIONS_TO_CONSIDER ||
- (minLongestInteraction && entry.duration > minLongestInteraction.latency)
- ) {
- // If the interaction already exists, update it. Otherwise create one.
- if (existingInteraction) {
- // If the new entry has a longer duration, replace the old entries,
- // otherwise add to the array.
- if (entry.duration > existingInteraction.latency) {
- existingInteraction.entries = [entry];
- existingInteraction.latency = entry.duration;
- } else if (
- entry.duration === existingInteraction.latency &&
- entry.startTime === existingInteraction.entries[0]?.startTime
- ) {
- existingInteraction.entries.push(entry);
- }
- } else {
- const interaction = {
- id: entry.interactionId!,
- latency: entry.duration,
- entries: [entry],
- };
- longestInteractionMap.set(interaction.id, interaction);
- longestInteractionList.push(interaction);
- }
-
- // Sort the entries by latency (descending) and keep only the top ten.
- longestInteractionList.sort((a, b) => b.latency - a.latency);
- if (longestInteractionList.length > MAX_INTERACTIONS_TO_CONSIDER) {
- longestInteractionList.splice(MAX_INTERACTIONS_TO_CONSIDER).forEach(i => longestInteractionMap.delete(i.id));
- }
- }
-};
diff --git a/packages/browser-utils/src/metrics/web-vitals/lib/onHidden.ts b/packages/browser-utils/src/metrics/web-vitals/lib/onHidden.ts
index 1844a616a479..5a3c1b4fc810 100644
--- a/packages/browser-utils/src/metrics/web-vitals/lib/onHidden.ts
+++ b/packages/browser-utils/src/metrics/web-vitals/lib/onHidden.ts
@@ -27,7 +27,7 @@ export interface OnHiddenCallback {
// The PR removed listening to the `pagehide` event, in favour of only listening to `visibilitychange` event.
// This is "more correct" but some browsers we still support (Safari <14.4) don't fully support `visibilitychange`
// or have known bugs w.r.t the `visibilitychange` event.
-// TODO (v10): If we decide to drop support for Safari 14.4, we can use the logic from web-vitals 4.2.4
+// TODO (v11): If we decide to drop support for Safari 14.4, we can use the logic from web-vitals 4.2.4
// In this case, we also need to update the integration tests that currently trigger the `pagehide` event to
// simulate the page being hidden.
export const onHidden = (cb: OnHiddenCallback) => {
diff --git a/packages/browser-utils/src/metrics/web-vitals/types.ts b/packages/browser-utils/src/metrics/web-vitals/types.ts
index 033fbee09926..8146849182b5 100644
--- a/packages/browser-utils/src/metrics/web-vitals/types.ts
+++ b/packages/browser-utils/src/metrics/web-vitals/types.ts
@@ -15,11 +15,9 @@
*/
export * from './types/base';
-export * from './types/polyfills';
export * from './types/cls';
export * from './types/fcp';
-export * from './types/fid'; // FIX was removed in 5.0.2 but we keep it around for now
export * from './types/inp';
export * from './types/lcp';
export * from './types/ttfb';
diff --git a/packages/browser-utils/src/metrics/web-vitals/types/base.ts b/packages/browser-utils/src/metrics/web-vitals/types/base.ts
index d8315b817f4a..02cb566011ac 100644
--- a/packages/browser-utils/src/metrics/web-vitals/types/base.ts
+++ b/packages/browser-utils/src/metrics/web-vitals/types/base.ts
@@ -16,7 +16,6 @@
import type { CLSMetric, CLSMetricWithAttribution } from './cls';
import type { FCPMetric, FCPMetricWithAttribution } from './fcp';
-import type { FIDMetric, FIDMetricWithAttribution } from './fid';
import type { INPMetric, INPMetricWithAttribution } from './inp';
import type { LCPMetric, LCPMetricWithAttribution } from './lcp';
import type { TTFBMetric, TTFBMetricWithAttribution } from './ttfb';
@@ -24,9 +23,8 @@ import type { TTFBMetric, TTFBMetricWithAttribution } from './ttfb';
export interface Metric {
/**
* The name of the metric (in acronym form).
- * // sentry: re-added FID here since we continue supporting it for now
*/
- name: 'CLS' | 'FCP' | 'FID' | 'INP' | 'LCP' | 'TTFB';
+ name: 'CLS' | 'FCP' | 'INP' | 'LCP' | 'TTFB';
/**
* The current value of the metric.
@@ -79,14 +77,12 @@ export interface Metric {
}
/** The union of supported metric types. */
-// sentry: re-added FIDMetric here since we continue supporting it for now
-export type MetricType = CLSMetric | FCPMetric | FIDMetric | INPMetric | LCPMetric | TTFBMetric;
+export type MetricType = CLSMetric | FCPMetric | INPMetric | LCPMetric | TTFBMetric;
/** The union of supported metric attribution types. */
export type MetricWithAttribution =
| CLSMetricWithAttribution
| FCPMetricWithAttribution
- | FIDMetricWithAttribution
| INPMetricWithAttribution
| LCPMetricWithAttribution
| TTFBMetricWithAttribution;
diff --git a/packages/browser-utils/src/metrics/web-vitals/types/fid.ts b/packages/browser-utils/src/metrics/web-vitals/types/fid.ts
deleted file mode 100644
index 953607adff98..000000000000
--- a/packages/browser-utils/src/metrics/web-vitals/types/fid.ts
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- * Copyright 2022 Google LLC
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * https://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-import type { LoadState, Metric } from './base';
-
-/**
- * An FID-specific version of the Metric object.
- */
-export interface FIDMetric extends Metric {
- name: 'FID';
- entries: PerformanceEventTiming[];
-}
-
-/**
- * An object containing potentially-helpful debugging information that
- * can be sent along with the FID value for the current page visit in order
- * to help identify issues happening to real-users in the field.
- */
-export interface FIDAttribution {
- /**
- * A selector identifying the element that the user interacted with. This
- * element will be the `target` of the `event` dispatched.
- */
- eventTarget: string;
- /**
- * The time when the user interacted. This time will match the `timeStamp`
- * value of the `event` dispatched.
- */
- eventTime: number;
- /**
- * The `type` of the `event` dispatched from the user interaction.
- */
- eventType: string;
- /**
- * The `PerformanceEventTiming` entry corresponding to FID.
- */
- eventEntry: PerformanceEventTiming;
- /**
- * The loading state of the document at the time when the first interaction
- * occurred (see `LoadState` for details). If the first interaction occurred
- * while the document was loading and executing script (e.g. usually in the
- * `dom-interactive` phase) it can result in long input delays.
- */
- loadState: LoadState;
-}
-
-/**
- * An FID-specific version of the Metric object with attribution.
- */
-export interface FIDMetricWithAttribution extends FIDMetric {
- attribution: FIDAttribution;
-}
diff --git a/packages/browser-utils/src/metrics/web-vitals/types/polyfills.ts b/packages/browser-utils/src/metrics/web-vitals/types/polyfills.ts
deleted file mode 100644
index c4314c0697fa..000000000000
--- a/packages/browser-utils/src/metrics/web-vitals/types/polyfills.ts
+++ /dev/null
@@ -1,21 +0,0 @@
-/*
- * Copyright 2022 Google LLC
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * https://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-export type FirstInputPolyfillEntry = Omit;
-
-export interface FirstInputPolyfillCallback {
- (entry: FirstInputPolyfillEntry): void;
-}
diff --git a/packages/replay-internal/src/coreHandlers/performanceObserver.ts b/packages/replay-internal/src/coreHandlers/performanceObserver.ts
index 638ef53b05fb..cd3a2aafed4b 100644
--- a/packages/replay-internal/src/coreHandlers/performanceObserver.ts
+++ b/packages/replay-internal/src/coreHandlers/performanceObserver.ts
@@ -1,6 +1,5 @@
import {
addClsInstrumentationHandler,
- addFidInstrumentationHandler,
addInpInstrumentationHandler,
addLcpInstrumentationHandler,
addPerformanceInstrumentationHandler,
@@ -8,7 +7,6 @@ import {
import type { ReplayContainer } from '../types';
import {
getCumulativeLayoutShift,
- getFirstInputDelay,
getInteractionToNextPaint,
getLargestContentfulPaint,
webVitalHandler,
@@ -39,7 +37,6 @@ export function setupPerformanceObserver(replay: ReplayContainer): () => void {
clearCallbacks.push(
addLcpInstrumentationHandler(webVitalHandler(getLargestContentfulPaint, replay)),
addClsInstrumentationHandler(webVitalHandler(getCumulativeLayoutShift, replay)),
- addFidInstrumentationHandler(webVitalHandler(getFirstInputDelay, replay)),
addInpInstrumentationHandler(webVitalHandler(getInteractionToNextPaint, replay)),
);
diff --git a/packages/replay-internal/src/types/replayFrame.ts b/packages/replay-internal/src/types/replayFrame.ts
index 6eb1855b8f8a..d060204256bf 100644
--- a/packages/replay-internal/src/types/replayFrame.ts
+++ b/packages/replay-internal/src/types/replayFrame.ts
@@ -172,7 +172,7 @@ interface ReplayHistoryFrame extends ReplayBaseSpanFrame {
interface ReplayWebVitalFrame extends ReplayBaseSpanFrame {
data: WebVitalData;
- op: 'largest-contentful-paint' | 'cumulative-layout-shift' | 'first-input-delay' | 'interaction-to-next-paint';
+ op: 'largest-contentful-paint' | 'cumulative-layout-shift' | 'interaction-to-next-paint';
}
interface ReplayMemoryFrame extends ReplayBaseSpanFrame {
diff --git a/packages/replay-internal/src/util/createPerformanceEntries.ts b/packages/replay-internal/src/util/createPerformanceEntries.ts
index 6df2343327fe..b8a39f233074 100644
--- a/packages/replay-internal/src/util/createPerformanceEntries.ts
+++ b/packages/replay-internal/src/util/createPerformanceEntries.ts
@@ -221,15 +221,6 @@ export function getCumulativeLayoutShift(metric: Metric): ReplayPerformanceEntry
return getWebVital(metric, 'cumulative-layout-shift', nodes, layoutShifts);
}
-/**
- * Add a FID event to the replay based on a FID metric.
- */
-export function getFirstInputDelay(metric: Metric): ReplayPerformanceEntry {
- const lastEntry = metric.entries[metric.entries.length - 1] as (PerformanceEntry & { target?: Node }) | undefined;
- const node = lastEntry?.target ? [lastEntry.target] : undefined;
- return getWebVital(metric, 'first-input-delay', node);
-}
-
/**
* Add an INP event to the replay based on an INP metric.
*/
diff --git a/packages/replay-internal/test/unit/util/createPerformanceEntry.test.ts b/packages/replay-internal/test/unit/util/createPerformanceEntry.test.ts
index a17c421c518b..c87d18bff325 100644
--- a/packages/replay-internal/test/unit/util/createPerformanceEntry.test.ts
+++ b/packages/replay-internal/test/unit/util/createPerformanceEntry.test.ts
@@ -4,7 +4,6 @@ import { WINDOW } from '../../../src/constants';
import {
createPerformanceEntries,
getCumulativeLayoutShift,
- getFirstInputDelay,
getInteractionToNextPaint,
getLargestContentfulPaint,
} from '../../../src/util/createPerformanceEntries';
@@ -108,26 +107,6 @@ describe('Unit | util | createPerformanceEntries', () => {
});
});
- describe('getFirstInputDelay', () => {
- it('works with an FID metric', async () => {
- const metric = {
- value: 5108.299,
- rating: 'good' as const,
- entries: [],
- };
-
- const event = getFirstInputDelay(metric);
-
- expect(event).toEqual({
- type: 'web-vital',
- name: 'first-input-delay',
- start: 1672531205.108299,
- end: 1672531205.108299,
- data: { value: 5108.299, size: 5108.299, rating: 'good', nodeIds: undefined, attributions: undefined },
- });
- });
- });
-
describe('getInteractionToNextPaint', () => {
it('works with an INP metric', async () => {
const metric = {