@grafana/faro-web-sdk
Version:
Faro instrumentations, metas, transports for web.
122 lines • 6.36 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.WebVitalsWithAttribution = void 0;
const attribution_1 = require("web-vitals/attribution");
const faro_core_1 = require("@grafana/faro-core");
const utils_1 = require("../../utils");
const instrumentationConstants_1 = require("../instrumentationConstants");
// duplicate keys saved in variables to save bundle size
// refs: https://github.com/grafana/faro-web-sdk/pull/595#discussion_r1615833968
const loadStateKey = 'load_state';
const timeToFirstByteKey = 'time_to_first_byte';
class WebVitalsWithAttribution {
constructor(corePushMeasurement, webVitalConfig) {
this.corePushMeasurement = corePushMeasurement;
this.webVitalConfig = webVitalConfig;
}
initialize() {
this.measureCLS();
this.measureFCP();
this.measureINP();
this.measureLCP();
this.measureTTFB();
}
measureCLS() {
var _a;
(0, attribution_1.onCLS)((metric) => {
const { loadState, largestShiftValue, largestShiftTime, largestShiftTarget } = metric.attribution;
const values = this.buildInitialValues(metric);
this.addIfPresent(values, 'largest_shift_value', largestShiftValue);
this.addIfPresent(values, 'largest_shift_time', largestShiftTime);
const context = this.buildInitialContext(metric);
this.addIfPresent(context, loadStateKey, loadState);
this.addIfPresent(context, 'largest_shift_target', largestShiftTarget);
this.pushMeasurement(values, context);
}, { reportAllChanges: (_a = this.webVitalConfig) === null || _a === void 0 ? void 0 : _a.reportAllChanges });
}
measureFCP() {
var _a;
(0, attribution_1.onFCP)((metric) => {
const { firstByteToFCP, timeToFirstByte, loadState } = metric.attribution;
const values = this.buildInitialValues(metric);
this.addIfPresent(values, 'first_byte_to_fcp', firstByteToFCP);
this.addIfPresent(values, timeToFirstByteKey, timeToFirstByte);
const context = this.buildInitialContext(metric);
this.addIfPresent(context, loadStateKey, loadState);
this.pushMeasurement(values, context);
}, { reportAllChanges: (_a = this.webVitalConfig) === null || _a === void 0 ? void 0 : _a.reportAllChanges });
}
measureINP() {
var _a;
(0, attribution_1.onINP)((metric) => {
const { interactionTime, presentationDelay, inputDelay, processingDuration, nextPaintTime, loadState, interactionTarget, interactionType, } = metric.attribution;
const values = this.buildInitialValues(metric);
this.addIfPresent(values, 'interaction_time', interactionTime);
this.addIfPresent(values, 'presentation_delay', presentationDelay);
this.addIfPresent(values, 'input_delay', inputDelay);
this.addIfPresent(values, 'processing_duration', processingDuration);
this.addIfPresent(values, 'next_paint_time', nextPaintTime);
const context = this.buildInitialContext(metric);
this.addIfPresent(context, loadStateKey, loadState);
this.addIfPresent(context, 'interaction_target', interactionTarget);
this.addIfPresent(context, 'interaction_type', interactionType);
this.pushMeasurement(values, context);
}, { reportAllChanges: (_a = this.webVitalConfig) === null || _a === void 0 ? void 0 : _a.reportAllChanges });
}
measureLCP() {
var _a;
(0, attribution_1.onLCP)((metric) => {
const { elementRenderDelay, resourceLoadDelay, resourceLoadDuration, timeToFirstByte, target } = metric.attribution;
const values = this.buildInitialValues(metric);
this.addIfPresent(values, 'element_render_delay', elementRenderDelay);
this.addIfPresent(values, 'resource_load_delay', resourceLoadDelay);
this.addIfPresent(values, 'resource_load_duration', resourceLoadDuration);
this.addIfPresent(values, timeToFirstByteKey, timeToFirstByte);
const context = this.buildInitialContext(metric);
this.addIfPresent(context, 'element', target);
this.pushMeasurement(values, context);
}, { reportAllChanges: (_a = this.webVitalConfig) === null || _a === void 0 ? void 0 : _a.reportAllChanges });
}
measureTTFB() {
var _a;
(0, attribution_1.onTTFB)((metric) => {
const { dnsDuration, connectionDuration, requestDuration, waitingDuration, cacheDuration } = metric.attribution;
const values = this.buildInitialValues(metric);
this.addIfPresent(values, 'dns_duration', dnsDuration);
this.addIfPresent(values, 'connection_duration', connectionDuration);
this.addIfPresent(values, 'request_duration', requestDuration);
this.addIfPresent(values, 'waiting_duration', waitingDuration);
this.addIfPresent(values, 'cache_duration', cacheDuration);
const context = this.buildInitialContext(metric);
this.pushMeasurement(values, context);
}, { reportAllChanges: (_a = this.webVitalConfig) === null || _a === void 0 ? void 0 : _a.reportAllChanges });
}
buildInitialValues(metric) {
const indicator = metric.name.toLowerCase();
return {
[indicator]: metric.value,
delta: metric.delta,
};
}
buildInitialContext(metric) {
var _a;
const navigationEntryId = (_a = (0, utils_1.getItem)(instrumentationConstants_1.NAVIGATION_ID_STORAGE_KEY, utils_1.webStorageType.session)) !== null && _a !== void 0 ? _a : faro_core_1.unknownString;
return {
id: metric.id,
rating: metric.rating,
navigation_type: metric.navigationType,
navigation_entry_id: navigationEntryId,
};
}
pushMeasurement(values, context) {
const type = 'web-vitals';
this.corePushMeasurement({ type, values }, { context });
}
addIfPresent(source, key, metric) {
if (metric) {
source[key] = metric;
}
}
}
exports.WebVitalsWithAttribution = WebVitalsWithAttribution;
//# sourceMappingURL=webVitalsWithAttribution.js.map