11function sendWebVitals ( ) {
2+ function getLoafAttribution ( attribution ) {
3+ if ( ! attribution ) {
4+ return { } ;
5+ }
6+
7+ const entry = attribution . eventEntry ;
8+
9+ if ( ! entry ) {
10+ return { } ;
11+ }
12+
13+ if ( ! PerformanceObserver . supportedEntryTypes . includes ( 'long-animation-frame' ) ) {
14+ return { } ;
15+ }
16+
17+ let loafAttribution = {
18+ debug_loaf_script_total_duration : 0
19+ } ;
20+
21+ const longAnimationFrames = performance . getEntriesByType ( 'long-animation-frame' ) ;
22+ longAnimationFrames . filter ( loaf => {
23+ // LoAFs that intersect with the event.
24+ return entry . startTime < ( loaf . startTime + loaf . duration ) && loaf . startTime < ( entry . startTime + entry . duration ) ;
25+ } ) . forEach ( loaf => {
26+ loaf . scripts . forEach ( script => {
27+ const totalDuration = script . startTime + script . duration - script . desiredExecutionStart ;
28+ if ( totalDuration > loafAttribution . debug_loaf_script_total_duration ) {
29+ loafAttribution = {
30+ // Stats for the LoAF entry itself.
31+ debug_loaf_entry_start_time : loaf . startTime ,
32+ debug_loaf_entry_end_time : loaf . startTime + loaf . duration ,
33+ debug_loaf_entry_work_duration : loaf . renderStart ? loaf . renderStart - loaf . startTime : loaf . duration ,
34+ debug_loaf_entry_render_duration : loaf . renderStart ? loaf . startTime + loaf . duration - loaf . renderStart : 0 ,
35+ debug_loaf_entry_total_forced_style_and_layout_duration : loaf . scripts . reduce ( ( sum , script ) => sum + script . forcedStyleAndLayoutDuration , 0 ) ,
36+ debug_loaf_entry_pre_layout_duration : loaf . styleAndLayoutStart ? loaf . styleAndLayoutStart - loaf . renderStart : 0 ,
37+ debug_loaf_entry_style_and_layout_duration : loaf . styleAndLayoutStart ? loaf . startTime + loaf . duration - loaf . styleAndLayoutStart : 0 ,
38+
39+ // Stats for the longest script in the LoAF entry.
40+ debug_loaf_script_total_duration : totalDuration ,
41+ debug_loaf_script_compile_duration : script . executionStart - script . startTime ,
42+ debug_loaf_script_exec_duration : script . startTime + script . duration - script . executionStart ,
43+ debug_loaf_script_invoker : script . invoker ,
44+ debug_loaf_script_type : script . invokerType ,
45+ debug_loaf_script_source_url : script . sourceURL ,
46+ debug_loaf_script_source_function_name : script . sourceFunctionName ,
47+ debug_loaf_script_source_char_position : script . sourceCharPosition ,
48+
49+ // LoAF metadata.
50+ debug_loaf_meta_length : longAnimationFrames . length ,
51+ }
52+ }
53+ } ) ;
54+ } ) ;
55+
56+ if ( ! loafAttribution . debug_loaf_script_total_duration ) {
57+ return { } ;
58+ }
59+
60+ // The LoAF script with the single longest total duration.
61+ return Object . fromEntries ( Object . entries ( loafAttribution ) . map ( ( [ k , v ] ) => {
62+ // Convert all floats to ints.
63+ return [ k , typeof v == 'number' ? Math . floor ( v ) : v ] ;
64+ } ) ) ;
65+ }
266
367 function sendWebVitalsGAEvents ( { name, delta, id, attribution, navigationType} ) {
468
@@ -22,11 +86,13 @@ function sendWebVitals() {
2286 break ;
2387 case 'FID' :
2488 case 'INP' :
89+ const loafAttribution = getLoafAttribution ( attribution ) ;
2590 overrides = {
2691 debug_event : attribution . eventType ,
2792 debug_time : Math . round ( attribution . eventTime ) ,
2893 debug_load_state : attribution . loadState ,
2994 debug_target : attribution . eventTarget || '(not set)' ,
95+ ...loafAttribution
3096 } ;
3197 if ( ! attribution . eventEntry ) {
3298 break ;
@@ -79,22 +145,20 @@ function sendWebVitals() {
79145 prefersColorScheme = 'not supported' ;
80146 }
81147
82- gtag ( 'event' , name , Object . assign (
83- {
84- event_category : 'Web Vitals' ,
85- value : Math . round ( name === 'CLS' ? delta * 1000 : delta ) ,
86- event_label : id ,
87- non_interaction : true ,
88-
89- //GA4
90- effective_type : effectiveType ,
91- data_saver : dataSaver ,
92- device_memory : deviceMemory ,
93- prefers_reduced_motion : prefersReducedMotion ,
94- prefers_color_scheme : prefersColorScheme ,
95- navigation_type : navigationType ,
96- } , overrides )
97- ) ;
148+ const params = Object . assign ( {
149+ event_category : 'Web Vitals' ,
150+ value : Math . round ( name === 'CLS' ? delta * 1000 : delta ) ,
151+ event_label : id ,
152+ non_interaction : true ,
153+ effective_type : effectiveType ,
154+ data_saver : dataSaver ,
155+ device_memory : deviceMemory ,
156+ prefers_reduced_motion : prefersReducedMotion ,
157+ prefers_color_scheme : prefersColorScheme ,
158+ navigation_type : navigationType ,
159+ } , overrides ) ;
160+
161+ gtag ( 'event' , name , params ) ;
98162
99163 }
100164
0 commit comments