@financial-times/n-tracking
Advanced tools
Comparing version 5.2.0 to 6.0.0
import oTracking from '@financial-times/o-tracking'; | ||
import oGrid from '@financial-times/o-grid'; | ||
import oViewport from '@financial-times/o-viewport'; | ||
import { onCLS, onFCP, onFID, onLCP, onTTFB } from 'web-vitals'; | ||
import readyState from 'ready-state'; | ||
@@ -129,4 +130,2 @@ | ||
var n={t:!1,i:!1,o:3e4},t=window,e=t.console,i=document,r=t.navigator,o=t.performance,u=function(){return r.deviceMemory},c=function(){return r.hardwareConcurrency},a=function(){return o&&!!o.getEntriesByType&&!!o.now&&!!o.mark},f="4g",s=!1,l=function(){return !!(c()&&c()<=4)||!!(u()&&u()<=4)},m=function(n,t){switch(n){case"slow-2g":case"2g":case"3g":return !0;default:return l()||t}},v={u:!1},d=function(n){i.hidden&&(n(),v.u=i.hidden);},p=function(n){return parseFloat(n.toFixed(4))},g=function(n){return "number"!=typeof n?null:p(n/Math.pow(1024,2))},b=[2e3,4e3],h=[2500,4e3],T=[.1,.25],k={ttfb:[200,500],fp:b,fcp:b,lcp:h,lcpFinal:h,fid:[100,300],cls:T,clsFinal:T,tbt:[300,600],ntbt:[400,600]},y=function(n,t){return k[n]?t<=k[n][0]?"good":t<=k[n][1]?"needsImprovement":"poor":null},w=function(e,i,o){var a;a=function(){v.u&&e.indexOf("Final")<0||!n.analyticsTracker||n.analyticsTracker({metricName:e,data:i,eventProperties:o||{},navigatorInformation:r?{deviceMemory:u()||0,hardwareConcurrency:c()||0,serviceWorkerStatus:"serviceWorker"in r?r.serviceWorker.controller?"controlled":"supported":"unsupported",isLowEndDevice:l(),isLowEndExperience:m(f,s)}:{},vitalsScore:y(e,i)});},"requestIdleCallback"in t?t.requestIdleCallback(a,{timeout:3e3}):a();},_=function(n,t,e){Object.keys(t).forEach((function(n){"number"==typeof t[n]&&(t[n]=p(t[n]));})),w(n,t,e);},F=function(t,e,i){var r=p(t);r<=n.o&&r>=0&&w(e,r,i);},E={},x={value:0},D={value:0},I={value:0},P={value:{beacon:0,css:0,fetch:0,img:0,other:0,script:0,total:0,xmlhttprequest:0}},j={value:0},q={value:0},C=function(n){var t=n.pop();t&&!t.s&&t.value&&(x.value+=t.value);},L={},O=function(n,t){try{var i=new PerformanceObserver((function(n){t(n.getEntries());}));return i.observe({type:n,buffered:!0}),i}catch(n){e.warn("Perfume.js:",n);}return null},S=function(n){L[n]&&L[n].disconnect(),delete L[n];},W=function(n){var t=n.pop();t&&F(t.processingStart-t.startTime,"fid",{performanceEntry:t}),S(1),F(I.value,"lcp"),L[3]&&"function"==typeof L[3].takeRecords&&L[3].takeRecords(),F(x.value,"cls"),setTimeout((function(){F(j.value,"tbt"),_("dataConsumption",P.value);}),1e4);},B=function(n){n.forEach((function(n){if(!("self"!==n.name||n.startTime<D.value)){var t=n.duration-50;t>0&&(j.value+=t,q.value+=t);}}));},M=function(n){n.forEach((function(n){"first-paint"===n.name?F(n.startTime,"fp"):"first-contentful-paint"===n.name&&(D.value=n.startTime,F(D.value,"fcp"),L[4]=O("longtask",B),S(0));}));},z=function(n){var t=n.pop();t&&(I.value=t.renderTime||t.loadTime);},H=function(n){n.forEach((function(n){n.identifier&&F(n.startTime,n.identifier);}));},N=function(t){t.forEach((function(t){if(n.t&&_("resourceTiming",t),t.decodedBodySize&&t.initiatorType){var e=t.decodedBodySize/1e3;P.value[t.initiatorType]+=e,P.value.total+=e;}}));},R=function(){L[2]&&(F(I.value,"lcpFinal"),S(2)),L[3]&&("function"==typeof L[3].takeRecords&&L[3].takeRecords(),F(x.value,"clsFinal"),S(3));},A=function(n){var t="usageDetails"in n?n.usageDetails:{};_("storageEstimate",{quota:g(n.quota),usage:g(n.usage),caches:g(t.caches),indexedDB:g(t.indexedDB),serviceWorker:g(t.serviceWorkerRegistrations)});},G=0,J=function(){function e(e){if(void 0===e&&(e={}),this.l="6.4.0",n.analyticsTracker=e.analyticsTracker,n.t=!!e.resourceTiming,n.i=!!e.elementTiming,n.o=e.maxMeasureTime||n.o,a()){"PerformanceObserver"in t&&(L[0]=O("paint",M),L[1]=O("first-input",W),L[2]=O("largest-contentful-paint",z),n.t&&O("resource",N),L[3]=O("layout-shift",C),n.i&&O("element",H)),void 0!==i.hidden&&i.addEventListener("visibilitychange",d.bind(this,R));var u=function(){if(!a())return {};var n=o.getEntriesByType("navigation")[0];if(!n)return {};var t=n.responseStart,e=n.responseEnd;return {fetchTime:e-n.fetchStart,workerTime:n.workerStart>0?e-n.workerStart:0,totalTime:e-n.requestStart,downloadTime:e-t,timeToFirstByte:t-n.requestStart,headerSize:n.transferSize-n.encodedBodySize||0,dnsLookupTime:n.domainLookupEnd-n.domainLookupStart,redirectTime:n.redirectEnd-n.redirectStart}}();_("navigationTiming",u),u.timeToFirstByte&&F(u.timeToFirstByte,"ttfb"),_("networkInformation",function(){if("connection"in r){var n=r.connection;return "object"!=typeof n?{}:(f=n.effectiveType,s=!!n.saveData,{downlink:n.downlink,effectiveType:n.effectiveType,rtt:n.rtt,saveData:!!n.saveData})}return {}}()),r&&r.storage&&"function"==typeof r.storage.estimate&&r.storage.estimate().then(A);}}return e.prototype.start=function(n){a()&&!E[n]&&(E[n]=!0,o.mark("mark_"+n+"_start"),v.u=!1);},e.prototype.end=function(n,t,e){if(void 0===t&&(t={}),void 0===e&&(e=!0),a()&&E[n]){o.mark("mark_"+n+"_end"),delete E[n];var i=function(n){o.measure(n,"mark_"+n+"_start","mark_"+n+"_end");var t=o.getEntriesByName(n).pop();return t&&"measure"===t.entryType?t.duration:-1}(n);e&&_(n,p(i),t);}},e.prototype.endPaint=function(n,t){var e=this;setTimeout((function(){e.end(n,t);}));},e.prototype.clear=function(n){delete E[n],o.clearMarks&&(o.clearMarks("mark_"+n+"_start"),o.clearMarks("mark_"+n+"_end"));},e.prototype.markNTBT=function(){var n=this;this.start("ntbt"),q.value=0,clearTimeout(G),G=setTimeout((function(){n.end("ntbt",{},!1),F(q.value,"ntbt"),q.value=0;}),2e3);},e}(); | ||
var commonjsGlobal = typeof globalThis !== 'undefined' ? globalThis : typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {}; | ||
@@ -328,8 +327,6 @@ | ||
'timeToFirstByte', | ||
'firstPaint', | ||
'largestContentfulPaint', | ||
'firstInputDelay', | ||
'cumulativeLayoutShift', | ||
'firstContentfulPaint', | ||
'totalBlockingTime' | ||
'firstContentfulPaint' | ||
]; | ||
@@ -372,3 +369,3 @@ | ||
/** | ||
* analyticsTracker() | ||
* recordMetric() | ||
* | ||
@@ -381,5 +378,10 @@ * This function is called every time one of the performance events occurs. | ||
const analyticsTracker = (({ metricName, data}) => { | ||
const recordMetric = ((metric) => { | ||
if (hasAlreadyBroadcast) return; | ||
// @see https://github.com/GoogleChrome/web-vitals#metric | ||
// for available properties of `metric` | ||
const metricName = metric.name.toLowerCase(); | ||
const data = metric.value; | ||
if (metricName === 'fid') { | ||
@@ -392,10 +394,6 @@ context.firstInputDelay = Math.round(data); | ||
context.timeToFirstByte = Math.round(data); | ||
} else if (metricName === 'fp') { | ||
context.firstPaint = Math.round(data); | ||
} else if (metricName === 'fcp'){ | ||
context.firstContentfulPaint = Math.round(data); | ||
} else if (metricName === 'cls') { | ||
context.cumulativeLayoutShift = data; | ||
} else if (metricName === 'tbt') { | ||
context.totalBlockingTime = Math.round(data); | ||
context.cumulativeLayoutShift = Number(data.toFixed(4)); | ||
} | ||
@@ -418,6 +416,7 @@ | ||
new J({ | ||
analyticsTracker, | ||
logging: false | ||
}); | ||
onCLS(recordMetric, { reportAllChanges: true }); | ||
onFCP(recordMetric); | ||
onFID(recordMetric); | ||
onLCP(recordMetric); | ||
onTTFB(recordMetric); | ||
}; | ||
@@ -424,0 +423,0 @@ |
@@ -14,5 +14,10 @@ 'use strict'; | ||
var symbols = Object.getOwnPropertySymbols(object); | ||
enumerableOnly && (symbols = symbols.filter(function (sym) { | ||
return Object.getOwnPropertyDescriptor(object, sym).enumerable; | ||
})), keys.push.apply(keys, symbols); | ||
if (enumerableOnly) { | ||
symbols = symbols.filter(function (sym) { | ||
return Object.getOwnPropertyDescriptor(object, sym).enumerable; | ||
}); | ||
} | ||
keys.push.apply(keys, symbols); | ||
} | ||
@@ -25,8 +30,15 @@ | ||
for (var i = 1; i < arguments.length; i++) { | ||
var source = null != arguments[i] ? arguments[i] : {}; | ||
i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { | ||
_defineProperty(target, key, source[key]); | ||
}) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { | ||
Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); | ||
}); | ||
var source = arguments[i] != null ? arguments[i] : {}; | ||
if (i % 2) { | ||
ownKeys(Object(source), true).forEach(function (key) { | ||
_defineProperty(target, key, source[key]); | ||
}); | ||
} else if (Object.getOwnPropertyDescriptors) { | ||
Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); | ||
} else { | ||
ownKeys(Object(source)).forEach(function (key) { | ||
Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); | ||
}); | ||
} | ||
} | ||
@@ -33,0 +45,0 @@ |
@@ -41,3 +41,3 @@ # Real user performance metrics | ||
This script will detect whether the browser supports performance timing, sample users based on their allocated Spoor ID, and initialise [Perfume.js](https://www.npmjs.com/package/perfume.js) to calculate the metrics. | ||
This script will detect whether the browser supports performance timing, sample users based on their allocated Spoor ID, and initialise [web-vitals](https://www.npmjs.com/package/web-vitals) to calculate the metrics. | ||
@@ -44,0 +44,0 @@ Once all metrics have been collected a `page:performance` event will be triggered and sent to Spoor. |
@@ -6,3 +6,3 @@ { | ||
"browser": "dist/browser.js", | ||
"version": "5.2.0", | ||
"version": "6.0.0", | ||
"license": "MIT", | ||
@@ -30,3 +30,2 @@ "repository": "Financial-Times/n-tracking.git", | ||
"jsdom": "^15.1.0", | ||
"perfume.js": "^6.3.0", | ||
"react": "^16.9.0", | ||
@@ -45,3 +44,4 @@ "rollup": "^1.31.0", | ||
"@financial-times/o-viewport": "^4.0.0", | ||
"ready-state": "^2.0.5" | ||
"ready-state": "^2.0.5", | ||
"web-vitals": "^3.0.0" | ||
}, | ||
@@ -48,0 +48,0 @@ "peerDependencies": { |
@@ -1,2 +0,2 @@ | ||
import Perfume from 'perfume.js'; | ||
import {onCLS, onFCP, onFID, onLCP, onTTFB} from 'web-vitals'; | ||
import readyState from 'ready-state'; | ||
@@ -12,8 +12,6 @@ import { broadcast } from '../broadcast'; | ||
'timeToFirstByte', | ||
'firstPaint', | ||
'largestContentfulPaint', | ||
'firstInputDelay', | ||
'cumulativeLayoutShift', | ||
'firstContentfulPaint', | ||
'totalBlockingTime' | ||
'firstContentfulPaint' | ||
]; | ||
@@ -56,3 +54,3 @@ | ||
/** | ||
* analyticsTracker() | ||
* recordMetric() | ||
* | ||
@@ -65,5 +63,10 @@ * This function is called every time one of the performance events occurs. | ||
const analyticsTracker = (({ metricName, data}) => { | ||
const recordMetric = ((metric) => { | ||
if (hasAlreadyBroadcast) return; | ||
// @see https://github.com/GoogleChrome/web-vitals#metric | ||
// for available properties of `metric` | ||
const metricName = metric.name.toLowerCase(); | ||
const data = metric.value; | ||
if (metricName === 'fid') { | ||
@@ -76,10 +79,6 @@ context.firstInputDelay = Math.round(data); | ||
context.timeToFirstByte = Math.round(data); | ||
} else if (metricName === 'fp') { | ||
context.firstPaint = Math.round(data); | ||
} else if (metricName === 'fcp'){ | ||
context.firstContentfulPaint = Math.round(data); | ||
} else if (metricName === 'cls') { | ||
context.cumulativeLayoutShift = data; | ||
} else if (metricName === 'tbt') { | ||
context.totalBlockingTime = Math.round(data); | ||
context.cumulativeLayoutShift = Number(data.toFixed(4)); | ||
} | ||
@@ -102,6 +101,7 @@ | ||
new Perfume({ | ||
analyticsTracker, | ||
logging: false | ||
}); | ||
onCLS(recordMetric, { reportAllChanges: true }); | ||
onFCP(recordMetric); | ||
onFID(recordMetric); | ||
onLCP(recordMetric); | ||
onTTFB(recordMetric); | ||
}; |
Sorry, the diff of this file is too big to display
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
1100151
16
44
28679
6
+ Addedweb-vitals@^3.0.0
+ Addedweb-vitals@3.5.2(transitive)