Skip to content

Instantly share code, notes, and snippets.

@ujjawalsidhpura
Last active October 9, 2024 10:09
Show Gist options
  • Save ujjawalsidhpura/7497b94b006573ef5f22b81292dd5a4c to your computer and use it in GitHub Desktop.
Save ujjawalsidhpura/7497b94b006573ef5f22b81292dd5a4c to your computer and use it in GitHub Desktop.
web-vitals-tracking-code
<!-- Google tag (gtag.js) -->
<script async src="https://www.googletagmanager.com/gtag/js?id=GA_TRACKING_ID"></script>
<script>
window.dataLayer = window.dataLayer || [];
function gtag(){window.dataLayer.push(arguments);}
gtag('js', new Date());
gtag('config', 'GA_TRACKING_ID');
</script>
<!-- Disable pageview measurement
gtag('config', 'GA_TRACKING_ID', { 'send_page_view': false });
-->
<!-- Configure additional Google Analytics properties
gtag('config', 'GA_TRACKING_ID_2');
-->
<script>
function getEffectiveConnectionType(){
var connection = navigator.connection || navigator.mozConnection || navigator.webkitConnection;
if(connection && connection.effectiveType) return connection.effectiveType;
return 'unknown';
}
</script>
<!-- Global site tag (gtag.js) - Google Analytics -->
<script async="async" src="https://www.googletagmanager.com/gtag/js?id=G-0BQR1PRHYJ"></script>
<script>
window.dataLayer = window.dataLayer || [];
function gtag(){dataLayer.push(arguments);}
gtag('js', new Date());
gtag('config', 'G-0BQR1PRHYJ', {
page_type: 'PAGE TYPE NAME',
effective_connection_type: getEffectiveConnectionType()
});
</script>
<script id="web-vitals-debug">
/*
* Debug Web Vitals in the field
*
* Functions to add Web Vitals debug info
*
* https://web.dev/debug-web-vitals-in-the-field/
*
*/
function getSelector(node, maxLen = 100) {
var 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 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) {
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)',
};
}
</script>
<script id="web-vitals-rating">
/*
* Get Web Vital Rating
*
*/
function getRating(name, value) {
switch (name) {
case 'LCP': return calculateRating(value,2500,4000);
case 'FID': return calculateRating(value,100,300);
case 'CLS': return calculateRating(value,0.1,0.25);
case 'FCP': return calculateRating(value,2000,4000); // Page Speed Insights is 1000 and 3000, lighthouse and web.dev does 2000 and 4000
case 'TTFB': return calculateRating(value,500,1500); // CrUX Data Studio report says NI is 500ms to 1500ms
default: return '(not set)';
}
}
function calculateRating(value, good, poor) {
if (!value && value !== 0) return '(not set)';
if (value > poor) return 'poor';
if (value > good) return 'ni';
return 'good';
}
</script>
<script id="web-vitals-ga4">
/*
* Send Core Web Vitals to Google Analytics 4
*
* https://github.com/GoogleChrome/web-vitals#using-gtagjs-google-analytics-4
*
* Modified to call getRating and getDebugInfo to add extra event data
*
*/
function sendToGoogleAnalytics({name, delta, value, id, entries}) {
// Assumes the global `gtag()` function exists, see:
// https://developers.google.com/analytics/devguides/collection/ga4
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, // Optional.
metric_delta: delta, // Optional.
// OPTIONAL: any additional params or debug info here.
// See: https://web.dev/debug-web-vitals-in-the-field/
// metric_rating: 'good' | 'ni' | 'poor',
metric_rating: getRating(name, value), // not used by my report
// debug_info: '...',
...getDebugInfo(name, entries)
});
}
</script>
<script id="web-vitals-cdn">
/*
* Using the web-vitals script from a CDN
*
* https://github.com/GoogleChrome/web-vitals#from-a-cdn
*
* Modified to call the sendToGoogleAnalytics function on events
*
*/
(function() {
var script = document.createElement('script');
script.src = 'https://unpkg.com/web-vitals';
script.onload = function() {
// When loading `web-vitals` using a classic script, all the public
// methods can be found on the `webVitals` global namespace.
webVitals.getCLS(sendToGoogleAnalytics);
webVitals.getFID(sendToGoogleAnalytics);
webVitals.getLCP(sendToGoogleAnalytics);
webVitals.getFCP(sendToGoogleAnalytics);
webVitals.getTTFB(sendToGoogleAnalytics);
}
document.head.appendChild(script);
}())
</script>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment