diff --git a/packages/rum-core/src/browser/performanceObservable.ts b/packages/rum-core/src/browser/performanceObservable.ts index dd7172da82..41872b4bc0 100644 --- a/packages/rum-core/src/browser/performanceObservable.ts +++ b/packages/rum-core/src/browser/performanceObservable.ts @@ -91,6 +91,7 @@ export interface RumLargestContentfulPaintTiming { startTime: RelativeTime size: number element?: Element + url?: string toJSON(): Omit } diff --git a/packages/rum-core/src/domain/view/trackViews.spec.ts b/packages/rum-core/src/domain/view/trackViews.spec.ts index feacbe5f62..dd59e8a7c2 100644 --- a/packages/rum-core/src/domain/view/trackViews.spec.ts +++ b/packages/rum-core/src/domain/view/trackViews.spec.ts @@ -531,7 +531,7 @@ describe('view metrics', () => { jasmine.objectContaining({ firstContentfulPaint: 123 as Duration, navigationTimings: jasmine.any(Object), - largestContentfulPaint: { value: 789 as Duration, targetSelector: undefined }, + largestContentfulPaint: { value: 789 as Duration, targetSelector: undefined, resourceUrl: undefined }, }) ) }) diff --git a/packages/rum-core/src/domain/view/viewCollection.spec.ts b/packages/rum-core/src/domain/view/viewCollection.spec.ts index 6257192f3a..3badb7dcb3 100644 --- a/packages/rum-core/src/domain/view/viewCollection.spec.ts +++ b/packages/rum-core/src/domain/view/viewCollection.spec.ts @@ -202,6 +202,7 @@ describe('viewCollection', () => { lcp: { timestamp: (10 * 1e6) as ServerDuration, target_selector: undefined, + resource_url: undefined, }, }, resource: { diff --git a/packages/rum-core/src/domain/view/viewCollection.ts b/packages/rum-core/src/domain/view/viewCollection.ts index 2f2d428397..0126475674 100644 --- a/packages/rum-core/src/domain/view/viewCollection.ts +++ b/packages/rum-core/src/domain/view/viewCollection.ts @@ -183,6 +183,7 @@ function computeViewPerformanceData( lcp: largestContentfulPaint && { timestamp: toServerDuration(largestContentfulPaint.value), target_selector: largestContentfulPaint.targetSelector, + resource_url: largestContentfulPaint.resourceUrl, }, } } diff --git a/packages/rum-core/src/domain/view/viewMetrics/trackLargestContentfulPaint.spec.ts b/packages/rum-core/src/domain/view/viewMetrics/trackLargestContentfulPaint.spec.ts index aa53ab0a26..b82a58b4f0 100644 --- a/packages/rum-core/src/domain/view/viewMetrics/trackLargestContentfulPaint.spec.ts +++ b/packages/rum-core/src/domain/view/viewMetrics/trackLargestContentfulPaint.spec.ts @@ -45,7 +45,11 @@ describe('trackLargestContentfulPaint', () => { startLCPTracking() notifyPerformanceEntries([createPerformanceEntry(RumPerformanceEntryType.LARGEST_CONTENTFUL_PAINT)]) - expect(lcpCallback).toHaveBeenCalledOnceWith({ value: 789 as RelativeTime, targetSelector: undefined }) + expect(lcpCallback).toHaveBeenCalledOnceWith({ + value: 789 as RelativeTime, + targetSelector: undefined, + resourceUrl: undefined, + }) }) it('should provide the largest contentful paint target selector', () => { @@ -56,7 +60,26 @@ describe('trackLargestContentfulPaint', () => { }), ]) - expect(lcpCallback).toHaveBeenCalledOnceWith({ value: 789 as RelativeTime, targetSelector: '#lcp-target-element' }) + expect(lcpCallback).toHaveBeenCalledOnceWith({ + value: 789 as RelativeTime, + targetSelector: '#lcp-target-element', + resourceUrl: undefined, + }) + }) + + it('should provide the largest contentful paint target url', () => { + startLCPTracking() + notifyPerformanceEntries([ + createPerformanceEntry(RumPerformanceEntryType.LARGEST_CONTENTFUL_PAINT, { + url: 'https://example.com/lcp-resource', + }), + ]) + + expect(lcpCallback).toHaveBeenCalledOnceWith({ + value: 789 as RelativeTime, + targetSelector: undefined, + resourceUrl: 'https://example.com/lcp-resource', + }) }) it('should be discarded if it is reported after a user interaction', () => { diff --git a/packages/rum-core/src/domain/view/viewMetrics/trackLargestContentfulPaint.ts b/packages/rum-core/src/domain/view/viewMetrics/trackLargestContentfulPaint.ts index 9aa9f420f1..f856909c9c 100644 --- a/packages/rum-core/src/domain/view/viewMetrics/trackLargestContentfulPaint.ts +++ b/packages/rum-core/src/domain/view/viewMetrics/trackLargestContentfulPaint.ts @@ -13,6 +13,7 @@ export const LCP_MAXIMUM_DELAY = 10 * ONE_MINUTE export interface LargestContentfulPaint { value: RelativeTime targetSelector?: string + resourceUrl?: string } /** @@ -57,7 +58,6 @@ export function trackLargestContentfulPaint( // https://bugs.chromium.org/p/chromium/issues/detail?id=1516655 entry.size > biggestLcpSize ) - if (lcpEntry) { let lcpTargetSelector if (lcpEntry.element) { @@ -67,6 +67,7 @@ export function trackLargestContentfulPaint( callback({ value: lcpEntry.startTime, targetSelector: lcpTargetSelector, + resourceUrl: lcpEntry.url, }) biggestLcpSize = lcpEntry.size } diff --git a/packages/rum-core/src/rawRumEvent.types.ts b/packages/rum-core/src/rawRumEvent.types.ts index c55e98ec2c..42cd308ead 100644 --- a/packages/rum-core/src/rawRumEvent.types.ts +++ b/packages/rum-core/src/rawRumEvent.types.ts @@ -175,6 +175,7 @@ export interface ViewPerformanceData { lcp?: { timestamp: ServerDuration target_selector?: string + resource_url?: string } } diff --git a/packages/rum-core/src/rumEvent.types.ts b/packages/rum-core/src/rumEvent.types.ts index aadff45b1f..960da731df 100644 --- a/packages/rum-core/src/rumEvent.types.ts +++ b/packages/rum-core/src/rumEvent.types.ts @@ -1712,6 +1712,10 @@ export interface ViewPerformanceData { * CSS selector path of the largest contentful paint element */ readonly target_selector?: string + /** + * URL of the largest contentful paint element + */ + readonly resource_url?: string [k: string]: unknown } [k: string]: unknown diff --git a/rum-events-format b/rum-events-format index a48cdd6c5d..6107e5d95e 160000 --- a/rum-events-format +++ b/rum-events-format @@ -1 +1 @@ -Subproject commit a48cdd6c5dac83b144519fa9d29615ea87d36905 +Subproject commit 6107e5d95eefa5f7cb32c9597641e4da011d52e5