Skip to content

Instantly share code, notes, and snippets.

@Kishorchandth
Created July 25, 2021 04:39
Show Gist options
  • Save Kishorchandth/139eb68b9b4923ae5b3638f8c17c6286 to your computer and use it in GitHub Desktop.
Save Kishorchandth/139eb68b9b4923ae5b3638f8c17c6286 to your computer and use it in GitHub Desktop.
Web-Vitals JS libraries
<script type="module">
// Load the web-vitals library from unpkg.com (or host locally):
import {getFCP, getLCP, getCLS, getTTFB, getFID} 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 sendWebVitals() {
function sendWebVitalsGAEvents({name, delta, id, entries}) {
if ("function" == typeof ga) {
let webVitalInfo = '(not set)';
// Set a custom dimension for more info for any CVW breaches
// 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];
webVitalInfo = getSelector(lastEntry.element);
} else if (name === 'FID') {
const firstEntry = entries[0];
webVitalInfo = getSelector(firstEntry.target);
} else if (name === 'CLS') {
const largestEntry = getLargestLayoutShiftEntry(entries);
if (largestEntry && largestEntry.sources) {
const largestSource = getLargestLayoutShiftSource(largestEntry.sources);
if (largestSource) {
webVitalInfo = getSelector(largestSource.node);
}
}
}
}
ga('send', 'event', {
eventCategory: 'Web Vitals',
eventAction: name,
// The `id` value will be unique to the current page load. When sending
// multiple values from the same page (e.g. for CLS), Google Analytics can
// compute a total by grouping on this ID (note: requires `eventLabel` to
// be a dimension in your report).
eventLabel: id,
// Google Analytics metrics must be integers, so the value is rounded.
// For CLS the value is first multiplied by 1000 for greater precision
// (note: increase the multiplier for greater precision if needed).
eventValue: Math.round(name === 'CLS' ? delta * 1000 : delta),
// Use a non-interaction event to avoid affecting bounce rate.
nonInteraction: true,
// Use `sendBeacon()` if the browser supports it.
transport: 'beacon',
// OPTIONAL: any additional params or debug info here.
// See: https://web.dev/debug-web-vitals-in-the-field/
// dimension1: '...',
// dimension2: '...',
dimension2: webVitalInfo
// ...
});
}
}
// Register function to send Core Web Vitals and other metrics as they become available
getFCP(sendWebVitalsGAEvents);
getLCP(sendWebVitalsGAEvents);
getCLS(sendWebVitalsGAEvents);
getTTFB(sendWebVitalsGAEvents);
getFID(sendWebVitalsGAEvents);
}
sendWebVitals();
</script>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment