diff --git a/dev-packages/browser-integration-tests/suites/tracing/metrics/web-vitals-lcp-standalone-spans/test.ts b/dev-packages/browser-integration-tests/suites/tracing/metrics/web-vitals-lcp-standalone-spans/test.ts index d0fa133f9567..9ced3b2dee07 100644 --- a/dev-packages/browser-integration-tests/suites/tracing/metrics/web-vitals-lcp-standalone-spans/test.ts +++ b/dev-packages/browser-integration-tests/suites/tracing/metrics/web-vitals-lcp-standalone-spans/test.ts @@ -60,7 +60,6 @@ sentryTest('captures LCP vital as a standalone span', async ({ getLocalTestUrl, 'user_agent.original': expect.stringContaining('Chrome'), 'sentry.pageload.span_id': expect.stringMatching(/[a-f0-9]{16}/), 'lcp.element': 'body > img', - 'lcp.id': '', 'lcp.loadTime': expect.any(Number), 'lcp.renderTime': expect.any(Number), 'lcp.size': expect.any(Number), diff --git a/packages/browser-utils/src/metrics/lcp.ts b/packages/browser-utils/src/metrics/lcp.ts index 4d4fbda8f979..abbe4348fa6f 100644 --- a/packages/browser-utils/src/metrics/lcp.ts +++ b/packages/browser-utils/src/metrics/lcp.ts @@ -44,7 +44,7 @@ export function trackLcpAsStandaloneSpan(): void { } sentSpan = true; if (pageloadSpanId) { - sendStandaloneLcpSpan(standaloneLcpValue, standaloneLcpEntry, pageloadSpanId); + _sendStandaloneLcpSpan(standaloneLcpValue, standaloneLcpEntry, pageloadSpanId); } cleanupLcpHandler(); } @@ -88,7 +88,14 @@ export function trackLcpAsStandaloneSpan(): void { }, 0); } -function sendStandaloneLcpSpan(lcpValue: number, entry: LargestContentfulPaint | undefined, pageloadSpanId: string) { +/** + * Exported only for testing! + */ +export function _sendStandaloneLcpSpan( + lcpValue: number, + entry: LargestContentfulPaint | undefined, + pageloadSpanId: string, +) { DEBUG_BUILD && logger.log(`Sending LCP span (${lcpValue})`); const startTime = msToSec((browserPerformanceTimeOrigin() || 0) + (entry?.startTime || 0)); @@ -105,12 +112,21 @@ function sendStandaloneLcpSpan(lcpValue: number, entry: LargestContentfulPaint | }; if (entry) { - attributes['lcp.element'] = htmlTreeAsString(entry.element); - attributes['lcp.id'] = entry.id; - attributes['lcp.url'] = entry.url; - attributes['lcp.loadTime'] = entry.loadTime; - attributes['lcp.renderTime'] = entry.renderTime; - attributes['lcp.size'] = entry.size; + entry.element && (attributes['lcp.element'] = htmlTreeAsString(entry.element)); + entry.id && (attributes['lcp.id'] = entry.id); + + // Trim URL to the first 200 characters. + entry.url && (attributes['lcp.url'] = entry.url.trim().slice(0, 200)); + + // loadTime is the time of LCP that's related to receiving the LCP element response.. + entry.loadTime != null && (attributes['lcp.loadTime'] = entry.loadTime); + + // renderTime is loadTime + rendering time + // it's 0 if the LCP element is loaded from a 3rd party origin that doesn't send the + // `Timing-Allow-Origin` header. + entry.renderTime != null && (attributes['lcp.renderTime'] = entry.renderTime); + + entry.size != null && (attributes['lcp.size'] = entry.size); } const span = startStandaloneWebVitalSpan({