Skip to content

ref(tracing): Reduce metrics bundle size #4432

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jan 21, 2022
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
154 changes: 69 additions & 85 deletions packages/tracing/src/browser/metrics.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ export class MetricsInstrumentation {
logger.log('[Tracing] Adding & adjusting spans using Performance API');

const timeOrigin = msToSec(browserPerformanceTimeOrigin);
let entryScriptSrc: string | undefined;
let entryScriptSrc = '';

if (global.document && global.document.scripts) {
// eslint-disable-next-line @typescript-eslint/prefer-for-of
Expand Down Expand Up @@ -114,7 +114,7 @@ export class MetricsInstrumentation {
const resourceName = (entry.name as string).replace(global.location.origin, '');
const endTimestamp = addResourceSpans(transaction, entry, resourceName, startTime, duration, timeOrigin);
// We remember the entry script end time to calculate the difference to the first init mark
if (entryScriptStartTimestamp === undefined && (entryScriptSrc || '').indexOf(resourceName) > -1) {
if (entryScriptStartTimestamp === undefined && entryScriptSrc.indexOf(resourceName) > -1) {
entryScriptStartTimestamp = endTimestamp;
}
break;
Expand Down Expand Up @@ -194,60 +194,11 @@ export class MetricsInstrumentation {
}

transaction.setMeasurements(this._measurements);
this._tagMetricInfo(transaction);

tagMetricInfo(transaction, this._lcpEntry, this._clsEntry);
transaction.setTag('sentry_reportAllChanges', this._reportAllChanges);
}
}

/** Add LCP / CLS data to transaction to allow debugging */
private _tagMetricInfo(transaction: Transaction): void {
if (this._lcpEntry) {
logger.log('[Measurements] Adding LCP Data');
// Capture Properties of the LCP element that contributes to the LCP.

if (this._lcpEntry.element) {
transaction.setTag('lcp.element', htmlTreeAsString(this._lcpEntry.element));
}

if (this._lcpEntry.id) {
transaction.setTag('lcp.id', this._lcpEntry.id);
}

if (this._lcpEntry.url) {
// Trim URL to the first 200 characters.
transaction.setTag('lcp.url', this._lcpEntry.url.trim().slice(0, 200));
}

transaction.setTag('lcp.size', this._lcpEntry.size);
}

// See: https://developer.mozilla.org/en-US/docs/Web/API/LayoutShift
if (this._clsEntry && this._clsEntry.sources) {
logger.log('[Measurements] Adding CLS Data');
this._clsEntry.sources.forEach((source, index) =>
transaction.setTag(`cls.source.${index + 1}`, htmlTreeAsString(source.node)),
);
}
}

/** Starts tracking the Cumulative Layout Shift on the current page. */
private _trackCLS(): void {
// See:
// https://web.dev/evolving-cls/
// https://web.dev/cls-web-tooling/
getCLS(metric => {
const entry = metric.entries.pop();
if (!entry) {
return;
}

logger.log('[Measurements] Adding CLS');
this._measurements['cls'] = { value: metric.value };
this._clsEntry = entry as LayoutShift;
});
}

/**
* Capture the information of the user agent.
*/
Expand Down Expand Up @@ -286,11 +237,27 @@ export class MetricsInstrumentation {
}
}

/** Starts tracking the Cumulative Layout Shift on the current page. */
private _trackCLS(): void {
// See:
// https://web.dev/evolving-cls/
// https://web.dev/cls-web-tooling/
getCLS(metric => {
const entry = metric.entries.pop();
if (!entry) {
return;
}

logger.log('[Measurements] Adding CLS');
this._measurements['cls'] = { value: metric.value };
this._clsEntry = entry as LayoutShift;
});
}

/** Starts tracking the Largest Contentful Paint on the current page. */
private _trackLCP(): void {
getLCP(metric => {
const entry = metric.entries.pop();

if (!entry) {
return;
}
Expand All @@ -308,7 +275,6 @@ export class MetricsInstrumentation {
private _trackFID(): void {
getFID(metric => {
const entry = metric.entries.pop();

if (!entry) {
return;
}
Expand All @@ -324,28 +290,12 @@ export class MetricsInstrumentation {

/** Instrument navigation entries */
function addNavigationSpans(transaction: Transaction, entry: Record<string, any>, timeOrigin: number): void {
addPerformanceNavigationTiming({ transaction, entry, event: 'unloadEvent', timeOrigin });
addPerformanceNavigationTiming({ transaction, entry, event: 'redirect', timeOrigin });
addPerformanceNavigationTiming({ transaction, entry, event: 'domContentLoadedEvent', timeOrigin });
addPerformanceNavigationTiming({ transaction, entry, event: 'loadEvent', timeOrigin });
addPerformanceNavigationTiming({ transaction, entry, event: 'connect', timeOrigin });
addPerformanceNavigationTiming({
transaction,
entry,
event: 'secureConnection',
timeOrigin,
eventEnd: 'connectEnd',
description: 'TLS/SSL',
['unloadEvent', 'redirect', 'domContentLoadedEvent', 'loadEvent', 'connect'].forEach(event => {
addPerformanceNavigationTiming(transaction, entry, event, timeOrigin);
});
addPerformanceNavigationTiming({
transaction,
entry,
event: 'fetch',
timeOrigin,
eventEnd: 'domainLookupStart',
description: 'cache',
});
addPerformanceNavigationTiming({ transaction, entry, event: 'domainLookup', timeOrigin, description: 'DNS' });
addPerformanceNavigationTiming(transaction, entry, 'secureConnection', timeOrigin, 'TLS/SSL', 'connectEnd');
addPerformanceNavigationTiming(transaction, entry, 'fetch', timeOrigin, 'cache', 'domainLookupStart');
addPerformanceNavigationTiming(transaction, entry, 'domainLookup', timeOrigin, 'DNS');
addRequest(transaction, entry, timeOrigin);
}

Expand Down Expand Up @@ -418,16 +368,14 @@ export function addResourceSpans(
}

/** Create performance navigation related spans */
function addPerformanceNavigationTiming(props: {
transaction: Transaction;
entry: Record<string, any>;
event: string;
timeOrigin: number;
eventEnd?: string;
description?: string;
}): void {
const { transaction, entry, event, timeOrigin, eventEnd, description } = props;

function addPerformanceNavigationTiming(
transaction: Transaction,
entry: Record<string, any>,
event: string,
timeOrigin: number,
description?: string,
eventEnd?: string,
): void {
const end = eventEnd ? (entry[eventEnd] as number | undefined) : (entry[`${event}End`] as number | undefined);
const start = entry[`${event}Start`] as number | undefined;
if (!start || !end) {
Expand Down Expand Up @@ -480,3 +428,39 @@ export function _startChild(transaction: Transaction, { startTimestamp, ...ctx }
function isMeasurementValue(value: any): boolean {
return typeof value === 'number' && isFinite(value);
}

/** Add LCP / CLS data to transaction to allow debugging */
function tagMetricInfo(
transaction: Transaction,
lcpEntry: MetricsInstrumentation['_lcpEntry'],
clsEntry: MetricsInstrumentation['_clsEntry'],
): void {
if (lcpEntry) {
logger.log('[Measurements] Adding LCP Data');

// Capture Properties of the LCP element that contributes to the LCP.

if (lcpEntry.element) {
transaction.setTag('lcp.element', htmlTreeAsString(lcpEntry.element));
}

if (lcpEntry.id) {
transaction.setTag('lcp.id', lcpEntry.id);
}

if (lcpEntry.url) {
// Trim URL to the first 200 characters.
transaction.setTag('lcp.url', lcpEntry.url.trim().slice(0, 200));
}

transaction.setTag('lcp.size', lcpEntry.size);
}

// See: https://developer.mozilla.org/en-US/docs/Web/API/LayoutShift
if (clsEntry && clsEntry.sources) {
logger.log('[Measurements] Adding CLS Data');
clsEntry.sources.forEach((source, index) =>
transaction.setTag(`cls.source.${index + 1}`, htmlTreeAsString(source.node)),
);
}
}