-
Notifications
You must be signed in to change notification settings - Fork 1
/
diagnostics.html
122 lines (110 loc) · 3.85 KB
/
diagnostics.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Web Vitals Test</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body>
<p><img style="max-width: 360px" src="https://placekitten.com/g/3840/2160" alt="Kitten" /></p>
<p>Text below image</p>
<!-- Global site tag (gtag.js) - Google Analytics -->
<script async src="https://www.googletagmanager.com/gtag/js?id=G-6N9K7KPH4H"></script>
<script>
window.dataLayer = window.dataLayer || [];
function gtag(){dataLayer.push(arguments);}
gtag('js', new Date());
gtag('config', 'G-6N9K7KPH4H');
</script>
<script type="module">
import {getCLS, getFID, getLCP} from 'https://unpkg.com/web-vitals?module';
function getSelector(node, maxLen = 100) {
let sel = '';
try {
while (node && node.nodeType !== 9) {
const part = node.id ? '#' + node.id : node.nodeName.toLowerCase() + (
(node.className && node.className.length) ?
'.' + Array.from(node.classList.values()).join('.') : '');
if (sel.length + part.length > maxLen - 1) return sel || part;
sel = sel ? part + '>' + sel : part;
if (node.id) break;
node = node.parentNode;
}
} catch (err) {
// Do nothing...
}
return sel;
}
function getLargestLayoutShiftEntry(entries) {
return entries.reduce((a, b) => a && a.value > b.value ? a : b);
}
function getLargestLayoutShiftSource(sources) {
return sources.reduce((a, b) => {
return a.node && a.previousRect.width * a.previousRect.height >
b.previousRect.width * b.previousRect.height ? a : b;
});
}
function wasFIDBeforeDCL(fidEntry) {
const navEntry = performance.getEntriesByType('navigation')[0];
return navEntry && fidEntry.startTime < navEntry.domContentLoadedEventStart;
}
function getFIDDebugTarget(entries) {
return entries[0].target;
}
function getFIDEventType(entries) {
return entries[0].name;
}
function getDebugInfo(name, entries = []) {
// In some cases there won't be any entries (e.g. if CLS is 0,
// or for LCP after a bfcache restore), so we have to check first.
if (entries.length) {
if (name === 'LCP') {
const lastEntry = entries[entries.length - 1];
return {
debug_target: getSelector(lastEntry.element),
event_time: lastEntry.startTime,
};
} else if (name === 'FID') {
const firstEntry = entries[0];
return {
debug_target: getSelector(firstEntry.target),
debug_event: firstEntry.name,
debug_timing: wasFIDBeforeDCL(firstEntry) ? 'pre_dcl' : 'post_dcl',
event_time: firstEntry.startTime,
};
} else if (name === 'CLS') {
const largestEntry = getLargestLayoutShiftEntry(entries);
if (largestEntry && largestEntry.sources && largestEntry.sources.length) {
const largestSource = getLargestLayoutShiftSource(largestEntry.sources);
if (largestSource) {
return {
debug_target: getSelector(largestSource.node),
event_time: largestEntry.startTime,
};
}
}
}
}
// Return default/empty params in case there are no entries.
return {
debug_target: '(not set)',
};
}
function sendToGoogleAnalytics({ name, delta, value, id, entries }) {
gtag('event', name, {
// Built-in params:
value: delta, // Use `delta` so the value can be summed.
// Custom params:
metric_id: id, // Needed to aggregate events.
metric_value: value, // Value for querying in BQ
metric_delta: delta, // Delta for querying in BQ
// Send the returned values from getDebugInfo() as custom parameters
...getDebugInfo(name, entries)
});
}
getLCP(sendToGoogleAnalytics);
getFID(sendToGoogleAnalytics);
getCLS(sendToGoogleAnalytics);
</script>
</body>
</html>