@@ -16,8 +16,10 @@ import {
1616} from '@sentry/core' ;
1717import { DEBUG_BUILD } from '../debug-build' ;
1818import { addClsInstrumentationHandler } from './instrument' ;
19+ import type { WebVitalReportEvent } from './utils' ;
1920import { msToSec , startStandaloneWebVitalSpan } from './utils' ;
2021import { onHidden } from './web-vitals/lib/onHidden' ;
22+ import { runOnce } from './web-vitals/lib/runOnce' ;
2123
2224/**
2325 * Starts tracking the Cumulative Layout Shift on the current page and collects the value once
@@ -37,16 +39,13 @@ export function trackClsAsStandaloneSpan(): void {
3739 return ;
3840 }
3941
40- let sentSpan = false ;
41- function _collectClsOnce ( ) {
42- if ( sentSpan ) {
43- return ;
44- }
45- sentSpan = true ;
46- if ( pageloadSpanId ) {
47- sendStandaloneClsSpan ( standaloneCLsValue , standaloneClsEntry , pageloadSpanId ) ;
48- }
49- cleanupClsHandler ( ) ;
42+ function _collectClsOnce ( reportEvent : WebVitalReportEvent ) {
43+ runOnce ( ( ) => {
44+ if ( pageloadSpanId ) {
45+ sendStandaloneClsSpan ( standaloneCLsValue , standaloneClsEntry , pageloadSpanId , reportEvent ) ;
46+ }
47+ cleanupClsHandler ( ) ;
48+ } ) ;
5049 }
5150
5251 const cleanupClsHandler = addClsInstrumentationHandler ( ( { metric } ) => {
@@ -59,7 +58,7 @@ export function trackClsAsStandaloneSpan(): void {
5958 } , true ) ;
6059
6160 onHidden ( ( ) => {
62- _collectClsOnce ( ) ;
61+ _collectClsOnce ( 'pagehide' ) ;
6362 } ) ;
6463
6564 // Since the call chain of this function is synchronous and evaluates before the SDK client is created,
@@ -73,9 +72,9 @@ export function trackClsAsStandaloneSpan(): void {
7372 }
7473
7574 const unsubscribeStartNavigation = client . on ( 'beforeStartNavigationSpan' , ( _ , options ) => {
76- // we only want to collect LCP if we actually navigate. Redirects should be ignored.
75+ // we only want to collect CLS if we actually navigate. Redirects should be ignored.
7776 if ( ! options ?. isRedirect ) {
78- _collectClsOnce ( ) ;
77+ _collectClsOnce ( 'navigation' ) ;
7978 unsubscribeStartNavigation ?.( ) ;
8079 }
8180 } ) ;
@@ -91,7 +90,12 @@ export function trackClsAsStandaloneSpan(): void {
9190 } , 0 ) ;
9291}
9392
94- function sendStandaloneClsSpan ( clsValue : number , entry : LayoutShift | undefined , pageloadSpanId : string ) {
93+ function sendStandaloneClsSpan (
94+ clsValue : number ,
95+ entry : LayoutShift | undefined ,
96+ pageloadSpanId : string ,
97+ reportEvent : WebVitalReportEvent ,
98+ ) {
9599 DEBUG_BUILD && logger . log ( `Sending CLS span (${ clsValue } )` ) ;
96100
97101 const startTime = msToSec ( ( browserPerformanceTimeOrigin ( ) || 0 ) + ( entry ?. startTime || 0 ) ) ;
@@ -105,6 +109,8 @@ function sendStandaloneClsSpan(clsValue: number, entry: LayoutShift | undefined,
105109 [ SEMANTIC_ATTRIBUTE_EXCLUSIVE_TIME ] : entry ?. duration || 0 ,
106110 // attach the pageload span id to the CLS span so that we can link them in the UI
107111 'sentry.pageload.span_id' : pageloadSpanId ,
112+ // describes what triggered the web vital to be reported
113+ 'sentry.report_event' : reportEvent ,
108114 } ;
109115
110116 // Add CLS sources as span attributes to help with debugging layout shifts
0 commit comments