Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
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

This comment has been minimized.

Copy link
Owner Author

@sgelob sgelob commented Jul 18, 2018

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

@bryanouuuu

This comment has been minimized.

Copy link

@bryanouuuu bryanouuuu commented Jul 16, 2019

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

This comment has been minimized.

Copy link
Owner Author

@sgelob 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