@@ -6,6 +6,8 @@ import { WINDOW } from '../helpers';
66
77const INTEGRATION_NAME = 'BFCacheMetrics' ;
88
9+ type BFCacheOutcome = 'hit' | 'miss' ;
10+
911type BFCacheFrame = 'top' | 'child' ;
1012
1113interface BFCacheIntegrationOptions {
@@ -51,68 +53,70 @@ export const bfcacheMetricsIntegration = defineIntegration((options: Partial<BFC
5153 return ;
5254 }
5355
54- WINDOW . addEventListener (
55- 'pageshow' ,
56- event => {
57- if ( event . persisted ) {
58- _captureBFCacheNavigation ( 'hit' ) ;
59- return ;
60- }
61-
62- const navigationEntry = WINDOW . performance . getEntriesByType ( 'navigation' ) [ 0 ] as
63- | NavigationTimingWithNotRestoredReasons
64- | undefined ;
65-
66- if ( navigationEntry ?. type !== 'back_forward' ) {
67- return ;
68- }
69-
70- const reasons = _collectNotRestoredReasons ( navigationEntry . notRestoredReasons , maxReasons ) ;
71-
72- _captureBFCacheNavigation ( 'miss' , reasons . length ) ;
73-
74- // Measures how expensive the fallback reload was when a back/forward navigation missed bfcache.
75- if ( typeof navigationEntry . duration === 'number' && navigationEntry . duration > 0 ) {
76- const transactionName = _getTransactionName ( ) ;
77-
78- metrics . distribution ( 'browser.bfcache.reload.duration' , navigationEntry . duration , {
79- unit : 'millisecond' ,
80- attributes : {
81- [ SENTRY_SEGMENT_NAME ] : transactionName ,
82- } ,
83- } ) ;
84- }
85-
86- reasons . forEach ( ( { reason, frame } ) => {
87- const transactionName = _getTransactionName ( ) ;
88-
89- metrics . count ( 'browser.bfcache.not_restored' , 1 , {
90- attributes : {
91- 'browser.bfcache.reason' : reason ,
92- 'browser.bfcache.frame' : frame ,
93- [ SENTRY_SEGMENT_NAME ] : transactionName ,
94- } ,
95- } ) ;
56+ function onPageShow ( event : PageTransitionEvent ) {
57+ const transactionName = _getTransactionName ( ) ;
58+ if ( event . persisted ) {
59+ _captureBFCacheNavigation ( 'hit' , undefined , transactionName ) ;
60+ return ;
61+ }
62+
63+ const navigationEntry = WINDOW . performance . getEntriesByType ( 'navigation' ) [ 0 ] as
64+ | NavigationTimingWithNotRestoredReasons
65+ | undefined ;
66+
67+ if ( navigationEntry ?. type !== 'back_forward' ) {
68+ return ;
69+ }
70+
71+ const reasons = _collectNotRestoredReasons ( navigationEntry . notRestoredReasons , maxReasons ) ;
72+ _captureBFCacheNavigation ( 'miss' , reasons . length , transactionName ) ;
73+
74+ // Measures how expensive the fallback reload was when a back/forward navigation missed bfcache.
75+ if ( typeof navigationEntry . duration === 'number' && navigationEntry . duration > 0 ) {
76+ metrics . distribution ( 'browser.bfcache.reload.duration' , navigationEntry . duration , {
77+ unit : 'millisecond' ,
78+ attributes : {
79+ [ SENTRY_SEGMENT_NAME ] : transactionName ,
80+ } ,
9681 } ) ;
97- } ,
98- true ,
99- ) ;
82+ }
83+
84+ reasons . forEach ( r => _captureBFCacheReason ( r , transactionName ) ) ;
85+ }
86+
87+ WINDOW . addEventListener ( 'pageshow' , onPageShow , true ) ;
10088 } ,
10189 } ;
10290} ) satisfies IntegrationFn ;
10391
104- function _captureBFCacheNavigation ( outcome : 'hit' | 'miss' , reasonCount ?: number ) : void {
105- const transactionName = _getTransactionName ( ) ;
106-
92+ /**
93+ * Captures a bf navigation as a metric and records the outcome and reason count.
94+ */
95+ function _captureBFCacheNavigation ( outcome : BFCacheOutcome , reasonCount ?: number , transactionName ?: string ) : void {
10796 metrics . count ( 'browser.bfcache.navigation' , 1 , {
10897 attributes : {
98+ // TODO: use convention constants
10999 'browser.bfcache.outcome' : outcome ,
110100 'browser.bfcache.not_restored_reason_count' : reasonCount ,
111101 [ SENTRY_SEGMENT_NAME ] : transactionName ,
112102 } ,
113103 } ) ;
114104}
115105
106+ /**
107+ * Maps a collected reason to a metric and captures/sends it.
108+ */
109+ function _captureBFCacheReason ( { reason, frame } : CollectedReason , transactionName ?: string ) {
110+ metrics . count ( 'browser.bfcache.not_restored' , 1 , {
111+ attributes : {
112+ // TODO: use convention constants
113+ 'browser.bfcache.reason' : reason ,
114+ 'browser.bfcache.frame' : frame ,
115+ [ SENTRY_SEGMENT_NAME ] : transactionName ,
116+ } ,
117+ } ) ;
118+ }
119+
116120function _getTransactionName ( ) : string | undefined {
117121 return getCurrentScope ( ) . getScopeData ( ) . transactionName || WINDOW . location ?. pathname ;
118122}
0 commit comments