Collect web-vitals whenever possible (#10054)

This commit is contained in:
William Durand 2021-02-09 16:50:11 +01:00 коммит произвёл GitHub
Родитель 9c0a4ba77c
Коммит a45526303c
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
6 изменённых файлов: 120 добавлений и 1 удалений

Просмотреть файл

@ -127,6 +127,7 @@ module.exports = {
'trackingEnabled',
'trackingId',
'trackingSendInitPageView',
'trackingSendWebVitals',
'unsupportedHrefLangs',
'validClientAppUrlExceptions',
'validClientApplications',
@ -294,6 +295,8 @@ module.exports = {
trackingId: 'UA-36116321-7',
// send a page view on initialization.
trackingSendInitPageView: true,
// send web vitals stats to GA
trackingSendWebVitals: false,
enablePostCssLoader: true,

Просмотреть файл

@ -13,6 +13,8 @@ module.exports = {
enableDevTools: true,
trackingSendWebVitals: true,
// Content security policy.
CSP: {
directives: {

Просмотреть файл

@ -252,6 +252,7 @@
"url-loader": "4.1.1",
"utf8": "3.0.0",
"uuid": "8.3.2",
"web-vitals": "1.1.0",
"webpack-isomorphic-tools": "3.0.6"
},
"devDependencies": {
@ -359,4 +360,4 @@
"maxSize": "33 kB"
}
]
}
}

Просмотреть файл

@ -3,6 +3,7 @@
import { oneLine } from 'common-tags';
import config from 'config';
import invariant from 'invariant';
import { getCLS, getFID, getLCP } from 'web-vitals';
import {
ADDON_TYPE_DICT,
@ -67,6 +68,9 @@ export function isDoNotTrackEnabled({
type TrackingParams = {|
_config: typeof config,
_isDoNotTrackEnabled: typeof isDoNotTrackEnabled,
_getCLS: typeof getCLS,
_getFID: typeof getFID,
_getLCP: typeof getLCP,
|};
export class Tracking {
@ -76,12 +80,17 @@ export class Tracking {
trackingEnabled: boolean;
sendWebVitals: boolean;
// Tracking ID
id: string;
constructor({
_config = config,
_isDoNotTrackEnabled = isDoNotTrackEnabled,
_getCLS = getCLS,
_getFID = getFID,
_getLCP = getLCP,
}: TrackingParams = {}) {
if (typeof window === 'undefined') {
return;
@ -133,9 +142,48 @@ export class Tracking {
// Set a custom dimension; this allows us to tell which front-end
// (addons-frontend vs addons-server) is being used in analytics.
ga('set', 'dimension3', 'addons-frontend');
if (convertBoolean(_config.get('trackingSendWebVitals'))) {
this.log('trackingSendWebVitals is enabled');
const sendWebVitalStats = this.sendWebVitalStats.bind(this);
_getCLS(sendWebVitalStats);
_getFID(sendWebVitalStats);
_getLCP(sendWebVitalStats);
}
}
}
sendWebVitalStats({
name,
delta,
id,
}: {|
name: string,
delta: number,
id: number,
|}) {
this.log('sendWebVitalStats', { name, delta, id });
this._ga('send', 'event', {
eventCategory: 'Web Vitals',
eventAction: name,
// The `id` value will be unique to the current page load. When sending
// multiple values from the same page (e.g. for CLS), Google Analytics
// can compute a total by grouping on this ID (note: requires
// `eventLabel` to be a dimension in your report).
eventLabel: id,
// Google Analytics metrics must be integers, so the value is rounded.
// For CLS the value is first multiplied by 1000 for greater precision
// (note: increase the multiplier for greater precision if needed).
eventValue: Math.round(name === 'CLS' ? delta * 1000 : delta),
// Use a non-interaction event to avoid affecting bounce rate.
nonInteraction: true,
// Use `sendBeacon()` if the browser supports it.
transport: 'beacon',
});
}
log(message: string, obj?: Object) {
if (this._log) {
const pattern = typeof obj === 'undefined' ? '%s %s' : '%s %s: %o';

Просмотреть файл

@ -200,6 +200,66 @@ describe(__filename, () => {
tracking.setDimension({ dimension, value });
sinon.assert.calledWith(window.ga, 'set', dimension, value);
});
it('should not send the web vitals when trackingSendWebVitals is false', () => {
const _getCLS = sinon.stub();
const _getFID = sinon.stub();
const _getLCP = sinon.stub();
createTracking({
configOverrides: { trackingSendWebVitals: false },
paramOverrides: {
_getCLS,
_getFID,
_getLCP,
},
});
sinon.assert.notCalled(_getCLS);
sinon.assert.notCalled(_getFID);
sinon.assert.notCalled(_getLCP);
});
it('should send the web vitals when trackingSendWebVitals is true', () => {
const _getCLS = sinon.stub();
const _getFID = sinon.stub();
const _getLCP = sinon.stub();
createTracking({
configOverrides: { trackingSendWebVitals: true },
paramOverrides: {
_getCLS,
_getFID,
_getLCP,
},
});
sinon.assert.calledOnce(_getCLS);
sinon.assert.calledOnce(_getFID);
sinon.assert.calledOnce(_getLCP);
});
});
describe('sendWebVitalStats', () => {
it('sends web vitals data to GA', () => {
const tracking = createTracking();
const fakeCLS = {
name: 'CLS',
id: 'some-id',
delta: 123,
};
tracking.sendWebVitalStats(fakeCLS);
sinon.assert.calledWith(window.ga, 'send', 'event', {
eventCategory: 'Web Vitals',
eventAction: fakeCLS.name,
eventLabel: fakeCLS.id,
eventValue: Math.round(fakeCLS.delta * 1000),
nonInteraction: true,
transport: 'beacon',
});
});
});
describe('getAddonTypeForTracking', () => {

Просмотреть файл

@ -17739,6 +17739,11 @@ web-namespaces@^1.0.0:
resolved "https://registry.yarnpkg.com/web-namespaces/-/web-namespaces-1.1.4.tgz#bc98a3de60dadd7faefc403d1076d529f5e030ec"
integrity sha512-wYxSGajtmoP4WxfejAPIr4l0fVh+jeMXZb08wNc0tMg6xsfZXj3cECqIK0G7ZAqUq0PP8WlMDtaOGVBTAWztNw==
web-vitals@1.1.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/web-vitals/-/web-vitals-1.1.0.tgz#7f410d9a1f7a1cd5d952806b45776204b47dc274"
integrity sha512-1cx54eRxY/+M0KNKdNpNnuXAXG+vJEvwScV4DiV9rOYDguHoeDIzm09ghBohOPtkqPO5OtPC14FWkNva3SDisg==
webidl-conversions@^4.0.2:
version "4.0.2"
resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-4.0.2.tgz#a855980b1f0b6b359ba1d5d9fb39ae941faa63ad"