Skip to content

Commit 259ec68

Browse files
authored
feat(web-vitals): Capture information about the LCP element culprit (#3427)
1 parent 18c0bf4 commit 259ec68

File tree

2 files changed

+35
-2
lines changed

2 files changed

+35
-2
lines changed

packages/tracing/src/browser/metrics.ts

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
11
/* eslint-disable max-lines */
22
/* eslint-disable @typescript-eslint/no-explicit-any */
33
import { Measurements, SpanContext } from '@sentry/types';
4-
import { browserPerformanceTimeOrigin, getGlobalObject, logger } from '@sentry/utils';
4+
import { browserPerformanceTimeOrigin, getGlobalObject, htmlTreeAsString, logger } from '@sentry/utils';
55

66
import { Span } from '../span';
77
import { Transaction } from '../transaction';
88
import { msToSec } from '../utils';
99
import { getCLS } from './web-vitals/getCLS';
1010
import { getFID } from './web-vitals/getFID';
11-
import { getLCP } from './web-vitals/getLCP';
11+
import { getLCP, LargestContentfulPaint } from './web-vitals/getLCP';
1212
import { getTTFB } from './web-vitals/getTTFB';
1313
import { getFirstHidden } from './web-vitals/lib/getFirstHidden';
1414
import { NavigatorDeviceMemory, NavigatorNetworkInformation } from './web-vitals/types';
@@ -20,6 +20,7 @@ export class MetricsInstrumentation {
2020
private _measurements: Measurements = {};
2121

2222
private _performanceCursor: number = 0;
23+
private _lcpEntry: LargestContentfulPaint | undefined;
2324

2425
public constructor() {
2526
if (global && global.performance) {
@@ -170,6 +171,26 @@ export class MetricsInstrumentation {
170171
}
171172

172173
transaction.setMeasurements(this._measurements);
174+
175+
if (this._lcpEntry) {
176+
logger.log('[Measurements] Adding LCP Data');
177+
// Capture Properties of the LCP element that contributes to the LCP.
178+
179+
if (this._lcpEntry.element) {
180+
transaction.setTag('lcp.element', htmlTreeAsString(this._lcpEntry.element));
181+
}
182+
183+
if (this._lcpEntry.id) {
184+
transaction.setTag('lcp.id', this._lcpEntry.id);
185+
}
186+
187+
if (this._lcpEntry.url) {
188+
// Trim URL to the first 200 characters.
189+
transaction.setTag('lcp.url', this._lcpEntry.url.trim().slice(0, 200));
190+
}
191+
192+
transaction.setTag('lcp.size', this._lcpEntry.size);
193+
}
173194
}
174195
}
175196

@@ -241,6 +262,7 @@ export class MetricsInstrumentation {
241262
logger.log('[Measurements] Adding LCP');
242263
this._measurements['lcp'] = { value: metric.value };
243264
this._measurements['mark.lcp'] = { value: timeOrigin + startTime };
265+
this._lcpEntry = entry as LargestContentfulPaint;
244266
});
245267
}
246268

packages/tracing/src/browser/web-vitals/getLCP.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,17 @@ import { onHidden } from './lib/onHidden';
2222
import { whenInput } from './lib/whenInput';
2323
import { ReportHandler } from './types';
2424

25+
// https://wicg.github.io/largest-contentful-paint/#sec-largest-contentful-paint-interface
26+
export interface LargestContentfulPaint extends PerformanceEntry {
27+
renderTime: DOMHighResTimeStamp;
28+
loadTime: DOMHighResTimeStamp;
29+
size: number;
30+
id: string;
31+
url: string;
32+
element?: Element;
33+
toJSON(): Record<string, string>;
34+
}
35+
2536
export const getLCP = (onReport: ReportHandler, reportAllChanges = false): void => {
2637
const metric = initMetric('LCP');
2738
const firstHidden = getFirstHidden();

0 commit comments

Comments
 (0)