Skip to content

Commit

Permalink
Merge pull request #134 from Financial-Times/rum-with-attribution
Browse files Browse the repository at this point in the history
feature: Add attribution option to RUM
  • Loading branch information
benwallman authored Mar 7, 2024
2 parents c57e079 + 322dc7c commit ece9181
Show file tree
Hide file tree
Showing 3 changed files with 86 additions and 0 deletions.
21 changes: 21 additions & 0 deletions docs/real-user-performance-metrics.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,3 +47,24 @@ Once all metrics have been collected a `page:performance` event will be triggere

A methodology and event data spec can be found here:
https://docs.google.com/document/d/1jG9f2DHs1AH-5kiV2cscpcheOckPM5EbzGA17uEGm9M/edit#

## With attribution

The above approach has a few issues: Firstly it takes the first bunch of events and sends them, whereas you want to capture the last events if possible.

Secondly, it doesn't tell us _why_ these values are what they are.

The workaround is to provide a more comprehensive real user monitoring option, which can be used simultaneously with the previous option.

The workaround utilises Web vital [attribution](https://www.npmjs.com/package/web-vitals#send-attribution-data) to these events, which helps determine what causes the scores, and can send multiple events of the same type per user.

To use this, alongside the previous option:

```js
import * as nTracking from '@financial-times/n-tracking';

if (flags.get('realUserMonitoringForPerformance')) {
nTracking.trackers.realUserMonitoringForPerformance();
nTracking.trackers.realUserMonitoringWithAttribution();
}
```
1 change: 1 addition & 0 deletions src/client/trackers/index.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
export * from './realUserMonitoringForPerformance';
export * from './realUserMonitoringWithAttribution';
export * from './pageAttention';
export * from './textCopying';
64 changes: 64 additions & 0 deletions src/client/trackers/realUserMonitoringWithAttribution.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
import { onLCP, onFID, onCLS } from 'web-vitals/attribution';
import { broadcast } from '../broadcast';
import { seedIsInSample } from '../utils/seedIsInSample';
import { getSpoorId } from '../utils/getSpoorId';

// 1% of users
const defaultSampleRate = 1;

const dataFromCWV = (metric) => {
if (metric.name === 'LCP') {
return {
name: metric.name,
lcp: metric.value,
lcpDelta: metric.delta,
element: metric.attribution.largestShiftTarget
};
}
if (metric.name === 'FID') {
return {
name: metric.name,
fid: metric.value,
fidDelta: metric.delta,
element: metric.attribution.eventTarget
};
}
if (metric.name === 'CLS') {
return {
name: metric.name,
cls: metric.value,
clsDelta: metric.delta,
element: metric.attribution.largestShiftTarget
};
}
};

export const realUserMonitoringWithAttribution = ({ sampleRate } = {}) => {
const broadcastCWV = (data) => {
broadcast('oTracking.event', {
action: 'performance-attribution',
category: 'page',
...dataFromCWV(data),
});
};

// Check browser support.
// @see https://developer.mozilla.org/en-US/docs/Web/API/PerformanceLongTaskTiming
if (!'PerformanceLongTaskTiming' in window) return;

const spoorId = getSpoorId();
const proportionToSample = sampleRate || defaultSampleRate;

// Gather metrics for only a cohort of users.
if (!seedIsInSample(spoorId, proportionToSample)) return;

// Proceed only if the page load event is a "navigate".
// @see: https://developer.mozilla.org/en-US/docs/Web/API/PerformanceNavigationTiming/type
// When testing, you will need to open a new browser window and paste the URL in i.e. simply reloading the page will not work.
const navigation = performance.getEntriesByType('navigation') && performance.getEntriesByType('navigation')[0];
if (!navigation || navigation.type !== 'navigate') return;

onCLS(broadcastCWV, { reportAllChanges: true });
onFID(broadcastCWV);
onLCP(broadcastCWV);
};

0 comments on commit ece9181

Please sign in to comment.