Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

@financial-times/n-tracking

Package Overview
Dependencies
Maintainers
18
Versions
44
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@financial-times/n-tracking - npm Package Compare versions

Comparing version 1.0.0 to 1.1.0-beta.1

src/client/trackers/real-user-monitoring-for-performance.js

112

dist/browser.js
import oTracking from '@financial-times/o-tracking';
import oGrid from '@financial-times/o-grid';
import oViewport from '@financial-times/o-viewport';
import Perfume from 'perfume.js';

@@ -119,2 +120,110 @@ function getUserData () {

/**
* userIsInCohort
*
* @param {integer} cohortPercent the percentage of users you want in your cohort.
* @returns {boolean} true if the user's spoor number is between zero and `cohortPercent`.
*/
const userIsInCohort = cohortPercent => {
if (!cohortPercent || isNaN(cohortPercent)) return false;
const { cookie } = document || {};
if (!cookie) return false;
let spoorNumber = false;
let isInCohort = false;
try {
spoorNumber = parseInt(decodeURIComponent(cookie.match(/spoor-id=([^;]+)/)[1].replace(/[^0-9]+/g,'')));
isInCohort = spoorNumber % 100 <= cohortPercent;
} catch (error) {
// The spoor id is not in the cohort percentile.
}
return isInCohort;
};
// Perfume.js is a web performance package.
// @see https://zizzamia.github.io/perfume/#/default-options/
const options = {
logging: false,
firstPaint: true,
largestContentfulPaint: true,
firstInputDelay: true,
largestContentfulPaint: true,
navigationTiming: true,
};
// @see "Important metrics to measure" https://web.dev/metrics
const requiredMetrics = [
'domInteractive',
'domComplete',
'timeToFirstByte',
'firstPaint',
'largestContentfulPaint',
'firstInputDelay'
];
const cohortPercent = 5;
const realUserMonitoringForPerformance = () => {
// Check browser support.
// @see https://developer.mozilla.org/en-US/docs/Web/API/PerformanceLongTaskTiming
if (!'PerformanceLongTaskTiming' in window) return;
// Gather metrics for only a cohort of users.
if (!userIsInCohort(cohortPercent)) return;
const navigation = performance.getEntriesByType('navigation')[0];
const { type, domInteractive, domComplete } = navigation;
// Proceed only if the page load event is a "navigate".
// @see: https://developer.mozilla.org/en-US/docs/Web/API/PerformanceNavigationTiming/type
if (type !== 'navigate') return;
const context = {
action: 'performance',
category: 'page',
domInteractive: Math.round(domInteractive),
domComplete: Math.round(domComplete),
};
/**
* analyticsTracker()
*
* This function is called every time one of the performance events occurs.
* The "final" event should be `firstInputDelay`, which is triggered by any "input" event (most likely to be a click.)
* Once all the metrics are present, it fires a broadcast() to the Spoor API.
*/
let hasAlreadyBroadcast = false;
options.analyticsTracker = (({ metricName, duration, data }) => {
if (hasAlreadyBroadcast) return;
if (duration) {
// Metrics with "duration":
// firstPaint, firstContentfulPaint, firstInputDelay and largestContentfulPaint
context[metricName] = Math.round(duration);
}
else if (metricName === 'navigationTiming') {
context.timeToFirstByte = Math.round(data.timeToFirstByte);
}
// Broadcast only if all the metrics are present
const contextContainsAllRequiredMetrics = requiredMetrics.every(metric => !isNaN(context[metric]));
if (contextContainsAllRequiredMetrics) {
console.log({performanceMetrics:context}); // eslint-disable-line no-console
broadcast('oTracking.event', context);
hasAlreadyBroadcast = true;
}
});
new Perfume(options);
};
// TODO: implement and test trackers copied over from n-ui
var index = /*#__PURE__*/Object.freeze({
__proto__: null,
realUserMonitoringForPerformance: realUserMonitoringForPerformance
});
const SPOOR_API_INGEST_URL = 'https://spoor-api.ft.com/ingest';

@@ -155,4 +264,3 @@

}
// export * from './trackers';
export { SPOOR_API_INGEST_URL, broadcast, init };
export { SPOOR_API_INGEST_URL, broadcast, init, index as trackers };

5

package.json

@@ -6,3 +6,3 @@ {

"browser": "dist/browser.js",
"version": "1.0.0",
"version": "1.1.0-beta.1",
"license": "MIT",

@@ -39,3 +39,4 @@ "repository": "Financial-Times/n-tracking.git",

"@financial-times/o-tracking": "^2.0.3",
"@financial-times/o-viewport": "^4.0.0"
"@financial-times/o-viewport": "^4.0.0",
"perfume.js": "^4.6.0"
},

@@ -42,0 +43,0 @@ "peerDependencies": {

@@ -21,18 +21,36 @@ # @financial-times/n-tracking [![CircleCI](https://circleci.com/gh/Financial-Times/n-tracking/tree/master.svg?style=svg)](https://circleci.com/gh/Financial-Times/n-tracking/tree/master)

On the client-side this package can be used to configure [o-tracking], setup click tracking, and send a page view event.
**Configure [o-tracking]**
This package can be used on the client-side. Initialise the component with [configuration options](#options).
```js
import * as nTracking from '@financial-times/n-tracking';
const options = {}
const oTracking = nTracking.init(options);
```
**Send custom events**
const oTracking = nTracking.init(options);
```js
import * as nTracking from '@financial-times/n-tracking';
const context = { customData: 12345 }
nTracking.broadcast('oTracking.event', {
category: 'page',
action: 'custom-event',
...context
});
```
To initialise the component you'll need to provide it with several [configuration options](#options).
**Send real-user-monitoring (RUM) performance metrics**
```js
import * as nTracking from '@financial-times/n-tracking';
if (flags.get('realUserMonitoringForPerformance')) {
nTracking.trackers.realUserMonitoringForPerformance();
}
```
<div><img width="70%" src="https://user-images.githubusercontent.com/224547/71626767-c709c480-2be6-11ea-91a5-506972a3b4d7.png" /></div>
_Above: Real-user-monitoring performance metrics are sent to spoor-api._
### Server-side integration

@@ -75,7 +93,7 @@

Property | Type | Required | Description
---------------|--------|----------|------------------------------------------------------------------
`appContext` | Object | Yes | [FT.com App Context] data describing the current page which will be appended to all captured events.
`extraContext` | Object | No | Additional data describing the current page which will be appended to all captured events.
`pageViewContext` | Object | No | Additional data to append to the page view event only
Property | Type | Required | Description
------------------|--------|----------|------------------------------------------------------------------
`appContext` | Object | Yes | [FT.com App Context] data describing the current page which will be appended to all captured events.
`extraContext` | Object | No | Additional data describing the current page which will be appended to all captured events.
`pageViewContext` | Object | No | Additional data to append to the page view event only

@@ -82,0 +100,0 @@ [FT.com App Context]: https://github.com/Financial-Times/dotcom-page-kit/blob/master/packages/dotcom-server-app-context/schema.md

@@ -44,2 +44,3 @@ import oTracking from '@financial-times/o-tracking';

export * from './broadcast';
// export * from './trackers';
import * as trackers from './trackers/index.js';
export { trackers };
// TODO: implement and test trackers copied over from n-ui
// https://github.com/Financial-Times/n-ui/tree/master/components/n-ui/tracking/ft/events
export {};
import { realUserMonitoringForPerformance } from './real-user-monitoring-for-performance';
export { realUserMonitoringForPerformance };

Sorry, the diff of this file is too big to display

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc