Skip to content

Instantly share code, notes, and snippets.

@sgelob
Last active March 14, 2021 05:03
Show Gist options
  • Save sgelob/110581ed66cf49a6d6c3b7ac33cdc17c to your computer and use it in GitHub Desktop.
Save sgelob/110581ed66cf49a6d6c3b7ac33cdc17c to your computer and use it in GitHub Desktop.
Real User Monitoring of Web Performance with Navigation Timing API, Google Tag Manager and Google Analytics
/**
* user-timing-api-RUM-gtm.js 1.0.1
* Olegs Belousovs @sgelob
*/
(function() {
"use strict";
// From https://github.com/addyosmani/timing.js/ –––>
var performance = window.performance || window.webkitPerformance || window.msPerformance || window.mozPerformance;
if (performance === undefined) {
return false;
}
// From https://developers.google.com/web/fundamentals/performance/critical-rendering-path/measure-crp –––>
var t = performance.timing,
// When DOM is ready
domInteractiveTime = t.domInteractive - t.domLoading,
// When both the DOM and CSSOM are ready
dcl = t.domContentLoadedEventStart - t.domLoading,
// When the page and all of its subresources are ready
domCompleteTime = t.domComplete - t.domLoading,
// From https://github.com/addyosmani/timing.js/ –––>
// Total time from start to load
loadTime = t.loadEventEnd - t.fetchStart,
// Time spent constructing the DOM tree
domReadyTime = t.domComplete - t.domInteractive,
// Time spent during redirection
redirectTime = t.redirectEnd - t.redirectStart,
// AppCache
appcacheTime = t.domainLookupStart - t.fetchStart,
// Time spent unloading documents
unloadEventTime = t.unloadEventEnd - t.unloadEventStart,
// Time spent during the request
requestTime = t.responseEnd - t.requestStart,
// Request to completion of the DOM loading
initDomTreeTime = t.domInteractive - t.responseEnd,
// Load event time
loadEventTime = t.loadEventEnd - t.loadEventStart;
// Time to First Paint
if (firstPaint === undefined) {
// All times are relative times to the start time within the
// same objects
var firstPaint = 0;
var firstPaintTime = 0;
// By bmdevel https://github.com/bmdevel/timing.js/blob/d5531b3b023367d467d3558061de8d8cf5b5ea79/timing.js –––>
if (typeof t.msFirstPaint === 'number') {
firstPaint = t.msFirstPaint;
firstPaintTime = firstPaint - t.navigationStart;
// All the rest
} else if (performance.getEntriesByName !== undefined) {
var firstPaintPerformanceEntry = performance.getEntriesByName('first-paint');
if (firstPaintPerformanceEntry.length === 1) {
firstPaintTime = firstPaintPerformanceEntry[0].startTime;
firstPaint = performance.timeOrigin + firstPaintTime;
firstPaintTime = firstPaintTime;
}
}
// By Olegs Belousovs @sgelob
// Push multiple variables and events to the data layer at once
dataLayer.push({
// Custom Event
"event": "WebPerfRUM",
// Critical Rendering Path
"DOMInteractive": domInteractiveTime,
"DOMContentLoaded": dcl,
"DOMComplete": domCompleteTime,
// Navigation Timing API metrics
"TotalTimeFromStartToLoad": loadTime,
"TimeSpentConstructingDOMTree": domReadyTime,
"TimeSpentDuringRedirection": redirectTime,
"AppCache": appcacheTime,
"TimeSpentUnloadingDocuments": unloadEventTime,
"TimeSpentDuringRequest": requestTime,
"RequestToCompletionOfDOMLoading": initDomTreeTime,
"LoadEventTime": loadEventTime,
// Time to first paint
"TimeToFirstPaint": firstPaintTime
});
}
})();
@sgelob
Copy link
Author

sgelob commented Jul 18, 2018

Implementation example in production https://www.bakeca.it/

@bryanouuuu
Copy link

Hello, i was looking for a way to follow thes metrics with gtm and i've seen your code, which is really good.
I've a little question, how do you implement this snippet? You just use a javascript variable on gtm?
Good job!

@sgelob
Copy link
Author

sgelob commented Jul 22, 2019

Hey Bryan, thank you!

You need to implement a series of variables in GTM and also Track Type – Timing… This code runs on all pages after Window Loaded. I made a talk on this argument, unfortunately only in Italian: https://www.youtube.com/watch?v=nyD54NEn0ac

Here you can find a JSON container, exported from my GTM https://gist.github.com/sgelob/0842d451186c332a45bcfee58224b0f3

Let me know if it helps you to move forward 😊

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment