@@ -309,3 +309,82 @@ export const VisuallyCompleteWithData = ({
309309    </ Profiler > 
310310  ) ; 
311311} ; 
312+ 
313+ interface  OpAssetMeasurementDefinition  { 
314+   key : string ; 
315+ } 
316+ 
317+ const  OP_ASSET_MEASUREMENT_MAP : Record < string ,  OpAssetMeasurementDefinition >  =  { 
318+   'resource.script' : { 
319+     key : 'script' , 
320+   } , 
321+   'resource.css' : { 
322+     key : 'css' , 
323+   } , 
324+   'resource.link' : { 
325+     key : 'link' , 
326+   } , 
327+   'resource.img' : { 
328+     key : 'img' , 
329+   } , 
330+ } ; 
331+ const  ASSET_MEASUREMENT_ALL  =  'allResources' ; 
332+ 
333+ export  const  MeasureAssetsOnTransaction  =  ( { children} : { children : ReactNode } )  =>  { 
334+   useEffect ( ( )  =>  { 
335+     try  { 
336+       const  transaction : any  =  getCurrentSentryReactTransaction ( ) ;  // Using any to override types for private api. 
337+       if  ( ! transaction )  { 
338+         return ; 
339+       } 
340+ 
341+       transaction . registerBeforeFinishCallback ( ( t : Transaction )  =>  { 
342+         const  spans : any [ ]  =  ( t  as  any ) . spanRecorder ?. spans ; 
343+         const  measurements  =  ( t  as  any ) . _measurements ; 
344+ 
345+         if  ( ! spans )  { 
346+           return ; 
347+         } 
348+ 
349+         if  ( measurements [ ASSET_MEASUREMENT_ALL ] )  { 
350+           return ; 
351+         } 
352+ 
353+         let  allTransfered  =  0 ; 
354+         let  allEncoded  =  0 ; 
355+         let  allCount  =  0 ; 
356+ 
357+         for  ( const  [ op ,  definition ]  of  Object . entries ( OP_ASSET_MEASUREMENT_MAP ) )  { 
358+           const  filtered  =  spans . filter ( s  =>  s . op  ===  op ) ; 
359+           const  count  =  filtered . length ; 
360+           const  transfered  =  filtered . reduce ( 
361+             ( acc ,  curr )  =>  acc  +  curr . data [ 'Transfer Size' ]  ??  0 , 
362+             0 
363+           ) ; 
364+           const  encoded  =  filtered . reduce ( 
365+             ( acc ,  curr )  =>  acc  +  curr . data [ 'Encoded Body Size' ]  ??  0 , 
366+             0 
367+           ) ; 
368+ 
369+           if  ( op  ===  'resource.script' )  { 
370+             t . setMeasurement ( `assets.${ definition . key }  ,  encoded ,  '' ) ; 
371+             t . setMeasurement ( `assets.${ definition . key }  ,  transfered ,  '' ) ; 
372+             t . setMeasurement ( `assets.${ definition . key }  ,  count ,  '' ) ; 
373+           } 
374+ 
375+           allCount  +=  count ; 
376+           allTransfered  +=  transfered ; 
377+           allEncoded  +=  encoded ; 
378+         } 
379+ 
380+         t . setMeasurement ( `${ ASSET_MEASUREMENT_ALL }  ,  allEncoded ,  '' ) ; 
381+         t . setMeasurement ( `${ ASSET_MEASUREMENT_ALL }  ,  allTransfered ,  '' ) ; 
382+         t . setMeasurement ( `${ ASSET_MEASUREMENT_ALL }  ,  allCount ,  '' ) ; 
383+       } ) ; 
384+     }  catch  ( _ )  { 
385+       // Defensive catch since this code is auxiliary. 
386+     } 
387+   } ,  [ ] ) ; 
388+ 
389+   return  < Fragment > { children } </ Fragment > ; 
390+ } ; 
0 commit comments