Skip to content

Instantly share code, notes, and snippets.

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 –––>
var performance = window.performance || window.webkitPerformance || window.msPerformance || window.mozPerformance;
if (performance === undefined) {
return false;
// From –––>
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 –––>
// 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 –––>
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
// 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

This comment has been minimized.

Copy link
Owner Author

@sgelob sgelob commented Jul 18, 2018

Implementation example in production


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!


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:

Here you can find a JSON container, exported from my GTM

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