@sentry-internal/browser-utils
Advanced tools
@@ -379,9 +379,10 @@ Object.defineProperty(exports, '__esModule', { value: true }); | ||
| utils.startAndEndSpan(span, measureStartTimestamp, measureEndTimestamp, { | ||
| name: entry.name , | ||
| op: entry.entryType , | ||
| attributes, | ||
| }); | ||
| return measureStartTimestamp; | ||
| // Measurements from third parties can be off, which would create invalid spans, dropping transactions in the process. | ||
| if (measureStartTimestamp <= measureEndTimestamp) { | ||
| utils.startAndEndSpan(span, measureStartTimestamp, measureEndTimestamp, { | ||
| name: entry.name , | ||
| op: entry.entryType , | ||
| attributes, | ||
| }); | ||
| } | ||
| } | ||
@@ -388,0 +389,0 @@ |
@@ -1,1 +0,1 @@ | ||
| {"version":3,"file":"browserMetrics.js","sources":["../../../src/metrics/browserMetrics.ts"],"sourcesContent":["/* eslint-disable max-lines */\nimport type { Measurements, Span, SpanAttributes, StartSpanOptions } from '@sentry/core';\nimport {\n SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN,\n browserPerformanceTimeOrigin,\n getActiveSpan,\n getComponentName,\n htmlTreeAsString,\n parseUrl,\n setMeasurement,\n spanToJSON,\n} from '@sentry/core';\nimport { WINDOW } from '../types';\nimport { trackClsAsStandaloneSpan } from './cls';\nimport {\n type PerformanceLongAnimationFrameTiming,\n addClsInstrumentationHandler,\n addFidInstrumentationHandler,\n addLcpInstrumentationHandler,\n addPerformanceInstrumentationHandler,\n addTtfbInstrumentationHandler,\n} from './instrument';\nimport {\n extractNetworkProtocol,\n getBrowserPerformanceAPI,\n isMeasurementValue,\n msToSec,\n startAndEndSpan,\n} from './utils';\nimport { getActivationStart } from './web-vitals/lib/getActivationStart';\nimport { getNavigationEntry } from './web-vitals/lib/getNavigationEntry';\nimport { getVisibilityWatcher } from './web-vitals/lib/getVisibilityWatcher';\n\ninterface NavigatorNetworkInformation {\n readonly connection?: NetworkInformation;\n}\n\n// http://wicg.github.io/netinfo/#connection-types\ntype ConnectionType = 'bluetooth' | 'cellular' | 'ethernet' | 'mixed' | 'none' | 'other' | 'unknown' | 'wifi' | 'wimax';\n\n// http://wicg.github.io/netinfo/#effectiveconnectiontype-enum\ntype EffectiveConnectionType = '2g' | '3g' | '4g' | 'slow-2g';\n\n// http://wicg.github.io/netinfo/#dom-megabit\ntype Megabit = number;\n// http://wicg.github.io/netinfo/#dom-millisecond\ntype Millisecond = number;\n\n// http://wicg.github.io/netinfo/#networkinformation-interface\ninterface NetworkInformation extends EventTarget {\n // http://wicg.github.io/netinfo/#type-attribute\n readonly type?: ConnectionType;\n // http://wicg.github.io/netinfo/#effectivetype-attribute\n readonly effectiveType?: EffectiveConnectionType;\n // http://wicg.github.io/netinfo/#downlinkmax-attribute\n readonly downlinkMax?: Megabit;\n // http://wicg.github.io/netinfo/#downlink-attribute\n readonly downlink?: Megabit;\n // http://wicg.github.io/netinfo/#rtt-attribute\n readonly rtt?: Millisecond;\n // http://wicg.github.io/netinfo/#savedata-attribute\n readonly saveData?: boolean;\n // http://wicg.github.io/netinfo/#handling-changes-to-the-underlying-connection\n onchange?: EventListener;\n}\n\n// https://w3c.github.io/device-memory/#sec-device-memory-js-api\ninterface NavigatorDeviceMemory {\n readonly deviceMemory?: number;\n}\n\nconst MAX_INT_AS_BYTES = 2147483647;\n\nlet _performanceCursor: number = 0;\n\nlet _measurements: Measurements = {};\nlet _lcpEntry: LargestContentfulPaint | undefined;\nlet _clsEntry: LayoutShift | undefined;\n\ninterface StartTrackingWebVitalsOptions {\n recordClsStandaloneSpans: boolean;\n}\n\n/**\n * Start tracking web vitals.\n * The callback returned by this function can be used to stop tracking & ensure all measurements are final & captured.\n *\n * @returns A function that forces web vitals collection\n */\nexport function startTrackingWebVitals({ recordClsStandaloneSpans }: StartTrackingWebVitalsOptions): () => void {\n const performance = getBrowserPerformanceAPI();\n if (performance && browserPerformanceTimeOrigin) {\n // @ts-expect-error we want to make sure all of these are available, even if TS is sure they are\n if (performance.mark) {\n WINDOW.performance.mark('sentry-tracing-init');\n }\n const fidCleanupCallback = _trackFID();\n const lcpCleanupCallback = _trackLCP();\n const ttfbCleanupCallback = _trackTtfb();\n const clsCleanupCallback = recordClsStandaloneSpans ? trackClsAsStandaloneSpan() : _trackCLS();\n\n return (): void => {\n fidCleanupCallback();\n lcpCleanupCallback();\n ttfbCleanupCallback();\n clsCleanupCallback && clsCleanupCallback();\n };\n }\n\n return () => undefined;\n}\n\n/**\n * Start tracking long tasks.\n */\nexport function startTrackingLongTasks(): void {\n addPerformanceInstrumentationHandler('longtask', ({ entries }) => {\n const parent = getActiveSpan();\n if (!parent) {\n return;\n }\n\n const { op: parentOp, start_timestamp: parentStartTimestamp } = spanToJSON(parent);\n\n for (const entry of entries) {\n const startTime = msToSec((browserPerformanceTimeOrigin as number) + entry.startTime);\n const duration = msToSec(entry.duration);\n\n if (parentOp === 'navigation' && parentStartTimestamp && startTime < parentStartTimestamp) {\n // Skip adding a span if the long task started before the navigation started.\n // `startAndEndSpan` will otherwise adjust the parent's start time to the span's start\n // time, potentially skewing the duration of the actual navigation as reported via our\n // routing instrumentations\n continue;\n }\n\n startAndEndSpan(parent, startTime, startTime + duration, {\n name: 'Main UI thread blocked',\n op: 'ui.long-task',\n attributes: {\n [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.ui.browser.metrics',\n },\n });\n }\n });\n}\n\n/**\n * Start tracking long animation frames.\n */\nexport function startTrackingLongAnimationFrames(): void {\n // NOTE: the current web-vitals version (3.5.2) does not support long-animation-frame, so\n // we directly observe `long-animation-frame` events instead of through the web-vitals\n // `observe` helper function.\n const observer = new PerformanceObserver(list => {\n const parent = getActiveSpan();\n if (!parent) {\n return;\n }\n for (const entry of list.getEntries() as PerformanceLongAnimationFrameTiming[]) {\n if (!entry.scripts[0]) {\n continue;\n }\n\n const startTime = msToSec((browserPerformanceTimeOrigin as number) + entry.startTime);\n\n const { start_timestamp: parentStartTimestamp, op: parentOp } = spanToJSON(parent);\n\n if (parentOp === 'navigation' && parentStartTimestamp && startTime < parentStartTimestamp) {\n // Skip adding the span if the long animation frame started before the navigation started.\n // `startAndEndSpan` will otherwise adjust the parent's start time to the span's start\n // time, potentially skewing the duration of the actual navigation as reported via our\n // routing instrumentations\n continue;\n }\n\n const duration = msToSec(entry.duration);\n\n const attributes: SpanAttributes = {\n [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.ui.browser.metrics',\n };\n\n const initialScript = entry.scripts[0];\n const { invoker, invokerType, sourceURL, sourceFunctionName, sourceCharPosition } = initialScript;\n attributes['browser.script.invoker'] = invoker;\n attributes['browser.script.invoker_type'] = invokerType;\n if (sourceURL) {\n attributes['code.filepath'] = sourceURL;\n }\n if (sourceFunctionName) {\n attributes['code.function'] = sourceFunctionName;\n }\n if (sourceCharPosition !== -1) {\n attributes['browser.script.source_char_position'] = sourceCharPosition;\n }\n\n startAndEndSpan(parent, startTime, startTime + duration, {\n name: 'Main UI thread blocked',\n op: 'ui.long-animation-frame',\n attributes,\n });\n }\n });\n\n observer.observe({ type: 'long-animation-frame', buffered: true });\n}\n\n/**\n * Start tracking interaction events.\n */\nexport function startTrackingInteractions(): void {\n addPerformanceInstrumentationHandler('event', ({ entries }) => {\n const parent = getActiveSpan();\n if (!parent) {\n return;\n }\n for (const entry of entries) {\n if (entry.name === 'click') {\n const startTime = msToSec((browserPerformanceTimeOrigin as number) + entry.startTime);\n const duration = msToSec(entry.duration);\n\n const spanOptions: StartSpanOptions & Required<Pick<StartSpanOptions, 'attributes'>> = {\n name: htmlTreeAsString(entry.target),\n op: `ui.interaction.${entry.name}`,\n startTime: startTime,\n attributes: {\n [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.ui.browser.metrics',\n },\n };\n\n const componentName = getComponentName(entry.target);\n if (componentName) {\n spanOptions.attributes['ui.component_name'] = componentName;\n }\n\n startAndEndSpan(parent, startTime, startTime + duration, spanOptions);\n }\n }\n });\n}\n\nexport { registerInpInteractionListener, startTrackingINP } from './inp';\n\n/**\n * Starts tracking the Cumulative Layout Shift on the current page and collects the value and last entry\n * to the `_measurements` object which ultimately is applied to the pageload span's measurements.\n */\nfunction _trackCLS(): () => void {\n return addClsInstrumentationHandler(({ metric }) => {\n const entry = metric.entries[metric.entries.length - 1] as LayoutShift | undefined;\n if (!entry) {\n return;\n }\n _measurements['cls'] = { value: metric.value, unit: '' };\n _clsEntry = entry;\n }, true);\n}\n\n/** Starts tracking the Largest Contentful Paint on the current page. */\nfunction _trackLCP(): () => void {\n return addLcpInstrumentationHandler(({ metric }) => {\n const entry = metric.entries[metric.entries.length - 1];\n if (!entry) {\n return;\n }\n\n _measurements['lcp'] = { value: metric.value, unit: 'millisecond' };\n _lcpEntry = entry as LargestContentfulPaint;\n }, true);\n}\n\n/** Starts tracking the First Input Delay on the current page. */\nfunction _trackFID(): () => void {\n return addFidInstrumentationHandler(({ metric }) => {\n const entry = metric.entries[metric.entries.length - 1];\n if (!entry) {\n return;\n }\n\n const timeOrigin = msToSec(browserPerformanceTimeOrigin as number);\n const startTime = msToSec(entry.startTime);\n _measurements['fid'] = { value: metric.value, unit: 'millisecond' };\n _measurements['mark.fid'] = { value: timeOrigin + startTime, unit: 'second' };\n });\n}\n\nfunction _trackTtfb(): () => void {\n return addTtfbInstrumentationHandler(({ metric }) => {\n const entry = metric.entries[metric.entries.length - 1];\n if (!entry) {\n return;\n }\n\n _measurements['ttfb'] = { value: metric.value, unit: 'millisecond' };\n });\n}\n\ninterface AddPerformanceEntriesOptions {\n /**\n * Flag to determine if CLS should be recorded as a measurement on the span or\n * sent as a standalone span instead.\n */\n recordClsOnPageloadSpan: boolean;\n}\n\n/** Add performance related spans to a transaction */\nexport function addPerformanceEntries(span: Span, options: AddPerformanceEntriesOptions): void {\n const performance = getBrowserPerformanceAPI();\n if (!performance || !performance.getEntries || !browserPerformanceTimeOrigin) {\n // Gatekeeper if performance API not available\n return;\n }\n\n const timeOrigin = msToSec(browserPerformanceTimeOrigin);\n\n const performanceEntries = performance.getEntries();\n\n const { op, start_timestamp: transactionStartTime } = spanToJSON(span);\n\n performanceEntries.slice(_performanceCursor).forEach(entry => {\n const startTime = msToSec(entry.startTime);\n const duration = msToSec(\n // Inexplicably, Chrome sometimes emits a negative duration. We need to work around this.\n // There is a SO post attempting to explain this, but it leaves one with open questions: https://stackoverflow.com/questions/23191918/peformance-getentries-and-negative-duration-display\n // The way we clamp the value is probably not accurate, since we have observed this happen for things that may take a while to load, like for example the replay worker.\n // TODO: Investigate why this happens and how to properly mitigate. For now, this is a workaround to prevent transactions being dropped due to negative duration spans.\n Math.max(0, entry.duration),\n );\n\n if (op === 'navigation' && transactionStartTime && timeOrigin + startTime < transactionStartTime) {\n return;\n }\n\n switch (entry.entryType) {\n case 'navigation': {\n _addNavigationSpans(span, entry as PerformanceNavigationTiming, timeOrigin);\n break;\n }\n case 'mark':\n case 'paint':\n case 'measure': {\n _addMeasureSpans(span, entry, startTime, duration, timeOrigin);\n\n // capture web vitals\n const firstHidden = getVisibilityWatcher();\n // Only report if the page wasn't hidden prior to the web vital.\n const shouldRecord = entry.startTime < firstHidden.firstHiddenTime;\n\n if (entry.name === 'first-paint' && shouldRecord) {\n _measurements['fp'] = { value: entry.startTime, unit: 'millisecond' };\n }\n if (entry.name === 'first-contentful-paint' && shouldRecord) {\n _measurements['fcp'] = { value: entry.startTime, unit: 'millisecond' };\n }\n break;\n }\n case 'resource': {\n _addResourceSpans(span, entry as PerformanceResourceTiming, entry.name, startTime, duration, timeOrigin);\n break;\n }\n // Ignore other entry types.\n }\n });\n\n _performanceCursor = Math.max(performanceEntries.length - 1, 0);\n\n _trackNavigator(span);\n\n // Measurements are only available for pageload transactions\n if (op === 'pageload') {\n _addTtfbRequestTimeToMeasurements(_measurements);\n\n const fidMark = _measurements['mark.fid'];\n if (fidMark && _measurements['fid']) {\n // create span for FID\n startAndEndSpan(span, fidMark.value, fidMark.value + msToSec(_measurements['fid'].value), {\n name: 'first input delay',\n op: 'ui.action',\n attributes: {\n [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.ui.browser.metrics',\n },\n });\n\n // Delete mark.fid as we don't want it to be part of final payload\n delete _measurements['mark.fid'];\n }\n\n // If FCP is not recorded we should not record the cls value\n // according to the new definition of CLS.\n // TODO: Check if the first condition is still necessary: `onCLS` already only fires once `onFCP` was called.\n if (!('fcp' in _measurements) || !options.recordClsOnPageloadSpan) {\n delete _measurements.cls;\n }\n\n Object.entries(_measurements).forEach(([measurementName, measurement]) => {\n setMeasurement(measurementName, measurement.value, measurement.unit);\n });\n\n // Set timeOrigin which denotes the timestamp which to base the LCP/FCP/FP/TTFB measurements on\n span.setAttribute('performance.timeOrigin', timeOrigin);\n\n // In prerendering scenarios, where a page might be prefetched and pre-rendered before the user clicks the link,\n // the navigation starts earlier than when the user clicks it. Web Vitals should always be based on the\n // user-perceived time, so they are not reported from the actual start of the navigation, but rather from the\n // time where the user actively started the navigation, for example by clicking a link.\n // This is user action is called \"activation\" and the time between navigation and activation is stored in\n // the `activationStart` attribute of the \"navigation\" PerformanceEntry.\n span.setAttribute('performance.activationStart', getActivationStart());\n\n _setWebVitalAttributes(span);\n }\n\n _lcpEntry = undefined;\n _clsEntry = undefined;\n _measurements = {};\n}\n\n/**\n * Create measure related spans.\n * Exported only for tests.\n */\nexport function _addMeasureSpans(\n span: Span,\n entry: PerformanceEntry,\n startTime: number,\n duration: number,\n timeOrigin: number,\n): number {\n const navEntry = getNavigationEntry(false);\n const requestTime = msToSec(navEntry ? navEntry.requestStart : 0);\n // Because performance.measure accepts arbitrary timestamps it can produce\n // spans that happen before the browser even makes a request for the page.\n //\n // An example of this is the automatically generated Next.js-before-hydration\n // spans created by the Next.js framework.\n //\n // To prevent this we will pin the start timestamp to the request start time\n // This does make duration inaccurate, so if this does happen, we will add\n // an attribute to the span\n const measureStartTimestamp = timeOrigin + Math.max(startTime, requestTime);\n const startTimeStamp = timeOrigin + startTime;\n const measureEndTimestamp = startTimeStamp + duration;\n\n const attributes: SpanAttributes = {\n [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.resource.browser.metrics',\n };\n\n if (measureStartTimestamp !== startTimeStamp) {\n attributes['sentry.browser.measure_happened_before_request'] = true;\n attributes['sentry.browser.measure_start_time'] = measureStartTimestamp;\n }\n\n startAndEndSpan(span, measureStartTimestamp, measureEndTimestamp, {\n name: entry.name as string,\n op: entry.entryType as string,\n attributes,\n });\n\n return measureStartTimestamp;\n}\n\n/** Instrument navigation entries */\nfunction _addNavigationSpans(span: Span, entry: PerformanceNavigationTiming, timeOrigin: number): void {\n (['unloadEvent', 'redirect', 'domContentLoadedEvent', 'loadEvent', 'connect'] as const).forEach(event => {\n _addPerformanceNavigationTiming(span, entry, event, timeOrigin);\n });\n _addPerformanceNavigationTiming(span, entry, 'secureConnection', timeOrigin, 'TLS/SSL');\n _addPerformanceNavigationTiming(span, entry, 'fetch', timeOrigin, 'cache');\n _addPerformanceNavigationTiming(span, entry, 'domainLookup', timeOrigin, 'DNS');\n\n _addRequest(span, entry, timeOrigin);\n}\n\ntype StartEventName =\n | 'secureConnection'\n | 'fetch'\n | 'domainLookup'\n | 'unloadEvent'\n | 'redirect'\n | 'connect'\n | 'domContentLoadedEvent'\n | 'loadEvent';\n\ntype EndEventName =\n | 'connectEnd'\n | 'domainLookupStart'\n | 'domainLookupEnd'\n | 'unloadEventEnd'\n | 'redirectEnd'\n | 'connectEnd'\n | 'domContentLoadedEventEnd'\n | 'loadEventEnd';\n\n/** Create performance navigation related spans */\nfunction _addPerformanceNavigationTiming(\n span: Span,\n entry: PerformanceNavigationTiming,\n event: StartEventName,\n timeOrigin: number,\n name: string = event,\n): void {\n const eventEnd = _getEndPropertyNameForNavigationTiming(event) satisfies keyof PerformanceNavigationTiming;\n const end = entry[eventEnd];\n const start = entry[`${event}Start`];\n if (!start || !end) {\n return;\n }\n startAndEndSpan(span, timeOrigin + msToSec(start), timeOrigin + msToSec(end), {\n op: `browser.${name}`,\n name: entry.name,\n attributes: {\n [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.ui.browser.metrics',\n },\n });\n}\n\nfunction _getEndPropertyNameForNavigationTiming(event: StartEventName): EndEventName {\n if (event === 'secureConnection') {\n return 'connectEnd';\n }\n if (event === 'fetch') {\n return 'domainLookupStart';\n }\n return `${event}End`;\n}\n\n/** Create request and response related spans */\nfunction _addRequest(span: Span, entry: PerformanceNavigationTiming, timeOrigin: number): void {\n const requestStartTimestamp = timeOrigin + msToSec(entry.requestStart as number);\n const responseEndTimestamp = timeOrigin + msToSec(entry.responseEnd as number);\n const responseStartTimestamp = timeOrigin + msToSec(entry.responseStart as number);\n if (entry.responseEnd) {\n // It is possible that we are collecting these metrics when the page hasn't finished loading yet, for example when the HTML slowly streams in.\n // In this case, ie. when the document request hasn't finished yet, `entry.responseEnd` will be 0.\n // In order not to produce faulty spans, where the end timestamp is before the start timestamp, we will only collect\n // these spans when the responseEnd value is available. The backend (Relay) would drop the entire span if it contained faulty spans.\n startAndEndSpan(span, requestStartTimestamp, responseEndTimestamp, {\n op: 'browser.request',\n name: entry.name,\n attributes: {\n [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.ui.browser.metrics',\n },\n });\n\n startAndEndSpan(span, responseStartTimestamp, responseEndTimestamp, {\n op: 'browser.response',\n name: entry.name,\n attributes: {\n [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.ui.browser.metrics',\n },\n });\n }\n}\n\n/**\n * Create resource-related spans.\n * Exported only for tests.\n */\nexport function _addResourceSpans(\n span: Span,\n entry: PerformanceResourceTiming,\n resourceUrl: string,\n startTime: number,\n duration: number,\n timeOrigin: number,\n): void {\n // we already instrument based on fetch and xhr, so we don't need to\n // duplicate spans here.\n if (entry.initiatorType === 'xmlhttprequest' || entry.initiatorType === 'fetch') {\n return;\n }\n\n const parsedUrl = parseUrl(resourceUrl);\n\n const attributes: SpanAttributes = {\n [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.resource.browser.metrics',\n };\n setResourceEntrySizeData(attributes, entry, 'transferSize', 'http.response_transfer_size');\n setResourceEntrySizeData(attributes, entry, 'encodedBodySize', 'http.response_content_length');\n setResourceEntrySizeData(attributes, entry, 'decodedBodySize', 'http.decoded_response_content_length');\n\n // `deliveryType` is experimental and does not exist everywhere\n const deliveryType = (entry as { deliveryType?: 'cache' | 'navigational-prefetch' | '' }).deliveryType;\n if (deliveryType != null) {\n attributes['http.response_delivery_type'] = deliveryType;\n }\n\n // Types do not reflect this property yet\n const renderBlockingStatus = (entry as { renderBlockingStatus?: 'render-blocking' | 'non-render-blocking' })\n .renderBlockingStatus;\n if (renderBlockingStatus) {\n attributes['resource.render_blocking_status'] = renderBlockingStatus;\n }\n\n if (parsedUrl.protocol) {\n attributes['url.scheme'] = parsedUrl.protocol.split(':').pop(); // the protocol returned by parseUrl includes a :, but OTEL spec does not, so we remove it.\n }\n\n if (parsedUrl.host) {\n attributes['server.address'] = parsedUrl.host;\n }\n\n attributes['url.same_origin'] = resourceUrl.includes(WINDOW.location.origin);\n\n const { name, version } = extractNetworkProtocol(entry.nextHopProtocol);\n attributes['network.protocol.name'] = name;\n attributes['network.protocol.version'] = version;\n\n const startTimestamp = timeOrigin + startTime;\n const endTimestamp = startTimestamp + duration;\n\n startAndEndSpan(span, startTimestamp, endTimestamp, {\n name: resourceUrl.replace(WINDOW.location.origin, ''),\n op: entry.initiatorType ? `resource.${entry.initiatorType}` : 'resource.other',\n attributes,\n });\n}\n\n/**\n * Capture the information of the user agent.\n */\nfunction _trackNavigator(span: Span): void {\n const navigator = WINDOW.navigator as null | (Navigator & NavigatorNetworkInformation & NavigatorDeviceMemory);\n if (!navigator) {\n return;\n }\n\n // track network connectivity\n const connection = navigator.connection;\n if (connection) {\n if (connection.effectiveType) {\n span.setAttribute('effectiveConnectionType', connection.effectiveType);\n }\n\n if (connection.type) {\n span.setAttribute('connectionType', connection.type);\n }\n\n if (isMeasurementValue(connection.rtt)) {\n _measurements['connection.rtt'] = { value: connection.rtt, unit: 'millisecond' };\n }\n }\n\n if (isMeasurementValue(navigator.deviceMemory)) {\n span.setAttribute('deviceMemory', `${navigator.deviceMemory} GB`);\n }\n\n if (isMeasurementValue(navigator.hardwareConcurrency)) {\n span.setAttribute('hardwareConcurrency', String(navigator.hardwareConcurrency));\n }\n}\n\n/** Add LCP / CLS data to span to allow debugging */\nfunction _setWebVitalAttributes(span: Span): void {\n if (_lcpEntry) {\n // Capture Properties of the LCP element that contributes to the LCP.\n\n if (_lcpEntry.element) {\n span.setAttribute('lcp.element', htmlTreeAsString(_lcpEntry.element));\n }\n\n if (_lcpEntry.id) {\n span.setAttribute('lcp.id', _lcpEntry.id);\n }\n\n if (_lcpEntry.url) {\n // Trim URL to the first 200 characters.\n span.setAttribute('lcp.url', _lcpEntry.url.trim().slice(0, 200));\n }\n\n if (_lcpEntry.loadTime != null) {\n // loadTime is the time of LCP that's related to receiving the LCP element response..\n span.setAttribute('lcp.loadTime', _lcpEntry.loadTime);\n }\n\n if (_lcpEntry.renderTime != null) {\n // renderTime is loadTime + rendering time\n // it's 0 if the LCP element is loaded from a 3rd party origin that doesn't send the\n // `Timing-Allow-Origin` header.\n span.setAttribute('lcp.renderTime', _lcpEntry.renderTime);\n }\n\n span.setAttribute('lcp.size', _lcpEntry.size);\n }\n\n // See: https://developer.mozilla.org/en-US/docs/Web/API/LayoutShift\n if (_clsEntry && _clsEntry.sources) {\n _clsEntry.sources.forEach((source, index) =>\n span.setAttribute(`cls.source.${index + 1}`, htmlTreeAsString(source.node)),\n );\n }\n}\n\nfunction setResourceEntrySizeData(\n attributes: SpanAttributes,\n entry: PerformanceResourceTiming,\n key: keyof Pick<PerformanceResourceTiming, 'transferSize' | 'encodedBodySize' | 'decodedBodySize'>,\n dataKey: 'http.response_transfer_size' | 'http.response_content_length' | 'http.decoded_response_content_length',\n): void {\n const entryVal = entry[key];\n if (entryVal != null && entryVal < MAX_INT_AS_BYTES) {\n attributes[dataKey] = entryVal;\n }\n}\n\n/**\n * Add ttfb request time information to measurements.\n *\n * ttfb information is added via vendored web vitals library.\n */\nfunction _addTtfbRequestTimeToMeasurements(_measurements: Measurements): void {\n const navEntry = getNavigationEntry(false);\n if (!navEntry) {\n return;\n }\n\n const { responseStart, requestStart } = navEntry;\n\n if (requestStart <= responseStart) {\n _measurements['ttfb.requestTime'] = {\n value: responseStart - requestStart,\n unit: 'millisecond',\n };\n }\n}\n"],"names":["getBrowserPerformanceAPI","browserPerformanceTimeOrigin","WINDOW","trackClsAsStandaloneSpan","addPerformanceInstrumentationHandler","getActiveSpan","spanToJSON","msToSec","startAndEndSpan","SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN","htmlTreeAsString","getComponentName","addClsInstrumentationHandler","addLcpInstrumentationHandler","addFidInstrumentationHandler","addTtfbInstrumentationHandler","getVisibilityWatcher","setMeasurement","getActivationStart","getNavigationEntry","parseUrl","extractNetworkProtocol","isMeasurementValue"],"mappings":"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"} | ||
| {"version":3,"file":"browserMetrics.js","sources":["../../../src/metrics/browserMetrics.ts"],"sourcesContent":["/* eslint-disable max-lines */\nimport type { Measurements, Span, SpanAttributes, StartSpanOptions } from '@sentry/core';\nimport {\n SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN,\n browserPerformanceTimeOrigin,\n getActiveSpan,\n getComponentName,\n htmlTreeAsString,\n parseUrl,\n setMeasurement,\n spanToJSON,\n} from '@sentry/core';\nimport { WINDOW } from '../types';\nimport { trackClsAsStandaloneSpan } from './cls';\nimport {\n type PerformanceLongAnimationFrameTiming,\n addClsInstrumentationHandler,\n addFidInstrumentationHandler,\n addLcpInstrumentationHandler,\n addPerformanceInstrumentationHandler,\n addTtfbInstrumentationHandler,\n} from './instrument';\nimport {\n extractNetworkProtocol,\n getBrowserPerformanceAPI,\n isMeasurementValue,\n msToSec,\n startAndEndSpan,\n} from './utils';\nimport { getActivationStart } from './web-vitals/lib/getActivationStart';\nimport { getNavigationEntry } from './web-vitals/lib/getNavigationEntry';\nimport { getVisibilityWatcher } from './web-vitals/lib/getVisibilityWatcher';\n\ninterface NavigatorNetworkInformation {\n readonly connection?: NetworkInformation;\n}\n\n// http://wicg.github.io/netinfo/#connection-types\ntype ConnectionType = 'bluetooth' | 'cellular' | 'ethernet' | 'mixed' | 'none' | 'other' | 'unknown' | 'wifi' | 'wimax';\n\n// http://wicg.github.io/netinfo/#effectiveconnectiontype-enum\ntype EffectiveConnectionType = '2g' | '3g' | '4g' | 'slow-2g';\n\n// http://wicg.github.io/netinfo/#dom-megabit\ntype Megabit = number;\n// http://wicg.github.io/netinfo/#dom-millisecond\ntype Millisecond = number;\n\n// http://wicg.github.io/netinfo/#networkinformation-interface\ninterface NetworkInformation extends EventTarget {\n // http://wicg.github.io/netinfo/#type-attribute\n readonly type?: ConnectionType;\n // http://wicg.github.io/netinfo/#effectivetype-attribute\n readonly effectiveType?: EffectiveConnectionType;\n // http://wicg.github.io/netinfo/#downlinkmax-attribute\n readonly downlinkMax?: Megabit;\n // http://wicg.github.io/netinfo/#downlink-attribute\n readonly downlink?: Megabit;\n // http://wicg.github.io/netinfo/#rtt-attribute\n readonly rtt?: Millisecond;\n // http://wicg.github.io/netinfo/#savedata-attribute\n readonly saveData?: boolean;\n // http://wicg.github.io/netinfo/#handling-changes-to-the-underlying-connection\n onchange?: EventListener;\n}\n\n// https://w3c.github.io/device-memory/#sec-device-memory-js-api\ninterface NavigatorDeviceMemory {\n readonly deviceMemory?: number;\n}\n\nconst MAX_INT_AS_BYTES = 2147483647;\n\nlet _performanceCursor: number = 0;\n\nlet _measurements: Measurements = {};\nlet _lcpEntry: LargestContentfulPaint | undefined;\nlet _clsEntry: LayoutShift | undefined;\n\ninterface StartTrackingWebVitalsOptions {\n recordClsStandaloneSpans: boolean;\n}\n\n/**\n * Start tracking web vitals.\n * The callback returned by this function can be used to stop tracking & ensure all measurements are final & captured.\n *\n * @returns A function that forces web vitals collection\n */\nexport function startTrackingWebVitals({ recordClsStandaloneSpans }: StartTrackingWebVitalsOptions): () => void {\n const performance = getBrowserPerformanceAPI();\n if (performance && browserPerformanceTimeOrigin) {\n // @ts-expect-error we want to make sure all of these are available, even if TS is sure they are\n if (performance.mark) {\n WINDOW.performance.mark('sentry-tracing-init');\n }\n const fidCleanupCallback = _trackFID();\n const lcpCleanupCallback = _trackLCP();\n const ttfbCleanupCallback = _trackTtfb();\n const clsCleanupCallback = recordClsStandaloneSpans ? trackClsAsStandaloneSpan() : _trackCLS();\n\n return (): void => {\n fidCleanupCallback();\n lcpCleanupCallback();\n ttfbCleanupCallback();\n clsCleanupCallback && clsCleanupCallback();\n };\n }\n\n return () => undefined;\n}\n\n/**\n * Start tracking long tasks.\n */\nexport function startTrackingLongTasks(): void {\n addPerformanceInstrumentationHandler('longtask', ({ entries }) => {\n const parent = getActiveSpan();\n if (!parent) {\n return;\n }\n\n const { op: parentOp, start_timestamp: parentStartTimestamp } = spanToJSON(parent);\n\n for (const entry of entries) {\n const startTime = msToSec((browserPerformanceTimeOrigin as number) + entry.startTime);\n const duration = msToSec(entry.duration);\n\n if (parentOp === 'navigation' && parentStartTimestamp && startTime < parentStartTimestamp) {\n // Skip adding a span if the long task started before the navigation started.\n // `startAndEndSpan` will otherwise adjust the parent's start time to the span's start\n // time, potentially skewing the duration of the actual navigation as reported via our\n // routing instrumentations\n continue;\n }\n\n startAndEndSpan(parent, startTime, startTime + duration, {\n name: 'Main UI thread blocked',\n op: 'ui.long-task',\n attributes: {\n [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.ui.browser.metrics',\n },\n });\n }\n });\n}\n\n/**\n * Start tracking long animation frames.\n */\nexport function startTrackingLongAnimationFrames(): void {\n // NOTE: the current web-vitals version (3.5.2) does not support long-animation-frame, so\n // we directly observe `long-animation-frame` events instead of through the web-vitals\n // `observe` helper function.\n const observer = new PerformanceObserver(list => {\n const parent = getActiveSpan();\n if (!parent) {\n return;\n }\n for (const entry of list.getEntries() as PerformanceLongAnimationFrameTiming[]) {\n if (!entry.scripts[0]) {\n continue;\n }\n\n const startTime = msToSec((browserPerformanceTimeOrigin as number) + entry.startTime);\n\n const { start_timestamp: parentStartTimestamp, op: parentOp } = spanToJSON(parent);\n\n if (parentOp === 'navigation' && parentStartTimestamp && startTime < parentStartTimestamp) {\n // Skip adding the span if the long animation frame started before the navigation started.\n // `startAndEndSpan` will otherwise adjust the parent's start time to the span's start\n // time, potentially skewing the duration of the actual navigation as reported via our\n // routing instrumentations\n continue;\n }\n\n const duration = msToSec(entry.duration);\n\n const attributes: SpanAttributes = {\n [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.ui.browser.metrics',\n };\n\n const initialScript = entry.scripts[0];\n const { invoker, invokerType, sourceURL, sourceFunctionName, sourceCharPosition } = initialScript;\n attributes['browser.script.invoker'] = invoker;\n attributes['browser.script.invoker_type'] = invokerType;\n if (sourceURL) {\n attributes['code.filepath'] = sourceURL;\n }\n if (sourceFunctionName) {\n attributes['code.function'] = sourceFunctionName;\n }\n if (sourceCharPosition !== -1) {\n attributes['browser.script.source_char_position'] = sourceCharPosition;\n }\n\n startAndEndSpan(parent, startTime, startTime + duration, {\n name: 'Main UI thread blocked',\n op: 'ui.long-animation-frame',\n attributes,\n });\n }\n });\n\n observer.observe({ type: 'long-animation-frame', buffered: true });\n}\n\n/**\n * Start tracking interaction events.\n */\nexport function startTrackingInteractions(): void {\n addPerformanceInstrumentationHandler('event', ({ entries }) => {\n const parent = getActiveSpan();\n if (!parent) {\n return;\n }\n for (const entry of entries) {\n if (entry.name === 'click') {\n const startTime = msToSec((browserPerformanceTimeOrigin as number) + entry.startTime);\n const duration = msToSec(entry.duration);\n\n const spanOptions: StartSpanOptions & Required<Pick<StartSpanOptions, 'attributes'>> = {\n name: htmlTreeAsString(entry.target),\n op: `ui.interaction.${entry.name}`,\n startTime: startTime,\n attributes: {\n [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.ui.browser.metrics',\n },\n };\n\n const componentName = getComponentName(entry.target);\n if (componentName) {\n spanOptions.attributes['ui.component_name'] = componentName;\n }\n\n startAndEndSpan(parent, startTime, startTime + duration, spanOptions);\n }\n }\n });\n}\n\nexport { registerInpInteractionListener, startTrackingINP } from './inp';\n\n/**\n * Starts tracking the Cumulative Layout Shift on the current page and collects the value and last entry\n * to the `_measurements` object which ultimately is applied to the pageload span's measurements.\n */\nfunction _trackCLS(): () => void {\n return addClsInstrumentationHandler(({ metric }) => {\n const entry = metric.entries[metric.entries.length - 1] as LayoutShift | undefined;\n if (!entry) {\n return;\n }\n _measurements['cls'] = { value: metric.value, unit: '' };\n _clsEntry = entry;\n }, true);\n}\n\n/** Starts tracking the Largest Contentful Paint on the current page. */\nfunction _trackLCP(): () => void {\n return addLcpInstrumentationHandler(({ metric }) => {\n const entry = metric.entries[metric.entries.length - 1];\n if (!entry) {\n return;\n }\n\n _measurements['lcp'] = { value: metric.value, unit: 'millisecond' };\n _lcpEntry = entry as LargestContentfulPaint;\n }, true);\n}\n\n/** Starts tracking the First Input Delay on the current page. */\nfunction _trackFID(): () => void {\n return addFidInstrumentationHandler(({ metric }) => {\n const entry = metric.entries[metric.entries.length - 1];\n if (!entry) {\n return;\n }\n\n const timeOrigin = msToSec(browserPerformanceTimeOrigin as number);\n const startTime = msToSec(entry.startTime);\n _measurements['fid'] = { value: metric.value, unit: 'millisecond' };\n _measurements['mark.fid'] = { value: timeOrigin + startTime, unit: 'second' };\n });\n}\n\nfunction _trackTtfb(): () => void {\n return addTtfbInstrumentationHandler(({ metric }) => {\n const entry = metric.entries[metric.entries.length - 1];\n if (!entry) {\n return;\n }\n\n _measurements['ttfb'] = { value: metric.value, unit: 'millisecond' };\n });\n}\n\ninterface AddPerformanceEntriesOptions {\n /**\n * Flag to determine if CLS should be recorded as a measurement on the span or\n * sent as a standalone span instead.\n */\n recordClsOnPageloadSpan: boolean;\n}\n\n/** Add performance related spans to a transaction */\nexport function addPerformanceEntries(span: Span, options: AddPerformanceEntriesOptions): void {\n const performance = getBrowserPerformanceAPI();\n if (!performance || !performance.getEntries || !browserPerformanceTimeOrigin) {\n // Gatekeeper if performance API not available\n return;\n }\n\n const timeOrigin = msToSec(browserPerformanceTimeOrigin);\n\n const performanceEntries = performance.getEntries();\n\n const { op, start_timestamp: transactionStartTime } = spanToJSON(span);\n\n performanceEntries.slice(_performanceCursor).forEach(entry => {\n const startTime = msToSec(entry.startTime);\n const duration = msToSec(\n // Inexplicably, Chrome sometimes emits a negative duration. We need to work around this.\n // There is a SO post attempting to explain this, but it leaves one with open questions: https://stackoverflow.com/questions/23191918/peformance-getentries-and-negative-duration-display\n // The way we clamp the value is probably not accurate, since we have observed this happen for things that may take a while to load, like for example the replay worker.\n // TODO: Investigate why this happens and how to properly mitigate. For now, this is a workaround to prevent transactions being dropped due to negative duration spans.\n Math.max(0, entry.duration),\n );\n\n if (op === 'navigation' && transactionStartTime && timeOrigin + startTime < transactionStartTime) {\n return;\n }\n\n switch (entry.entryType) {\n case 'navigation': {\n _addNavigationSpans(span, entry as PerformanceNavigationTiming, timeOrigin);\n break;\n }\n case 'mark':\n case 'paint':\n case 'measure': {\n _addMeasureSpans(span, entry, startTime, duration, timeOrigin);\n\n // capture web vitals\n const firstHidden = getVisibilityWatcher();\n // Only report if the page wasn't hidden prior to the web vital.\n const shouldRecord = entry.startTime < firstHidden.firstHiddenTime;\n\n if (entry.name === 'first-paint' && shouldRecord) {\n _measurements['fp'] = { value: entry.startTime, unit: 'millisecond' };\n }\n if (entry.name === 'first-contentful-paint' && shouldRecord) {\n _measurements['fcp'] = { value: entry.startTime, unit: 'millisecond' };\n }\n break;\n }\n case 'resource': {\n _addResourceSpans(span, entry as PerformanceResourceTiming, entry.name, startTime, duration, timeOrigin);\n break;\n }\n // Ignore other entry types.\n }\n });\n\n _performanceCursor = Math.max(performanceEntries.length - 1, 0);\n\n _trackNavigator(span);\n\n // Measurements are only available for pageload transactions\n if (op === 'pageload') {\n _addTtfbRequestTimeToMeasurements(_measurements);\n\n const fidMark = _measurements['mark.fid'];\n if (fidMark && _measurements['fid']) {\n // create span for FID\n startAndEndSpan(span, fidMark.value, fidMark.value + msToSec(_measurements['fid'].value), {\n name: 'first input delay',\n op: 'ui.action',\n attributes: {\n [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.ui.browser.metrics',\n },\n });\n\n // Delete mark.fid as we don't want it to be part of final payload\n delete _measurements['mark.fid'];\n }\n\n // If FCP is not recorded we should not record the cls value\n // according to the new definition of CLS.\n // TODO: Check if the first condition is still necessary: `onCLS` already only fires once `onFCP` was called.\n if (!('fcp' in _measurements) || !options.recordClsOnPageloadSpan) {\n delete _measurements.cls;\n }\n\n Object.entries(_measurements).forEach(([measurementName, measurement]) => {\n setMeasurement(measurementName, measurement.value, measurement.unit);\n });\n\n // Set timeOrigin which denotes the timestamp which to base the LCP/FCP/FP/TTFB measurements on\n span.setAttribute('performance.timeOrigin', timeOrigin);\n\n // In prerendering scenarios, where a page might be prefetched and pre-rendered before the user clicks the link,\n // the navigation starts earlier than when the user clicks it. Web Vitals should always be based on the\n // user-perceived time, so they are not reported from the actual start of the navigation, but rather from the\n // time where the user actively started the navigation, for example by clicking a link.\n // This is user action is called \"activation\" and the time between navigation and activation is stored in\n // the `activationStart` attribute of the \"navigation\" PerformanceEntry.\n span.setAttribute('performance.activationStart', getActivationStart());\n\n _setWebVitalAttributes(span);\n }\n\n _lcpEntry = undefined;\n _clsEntry = undefined;\n _measurements = {};\n}\n\n/**\n * Create measure related spans.\n * Exported only for tests.\n */\nexport function _addMeasureSpans(\n span: Span,\n entry: PerformanceEntry,\n startTime: number,\n duration: number,\n timeOrigin: number,\n): void {\n const navEntry = getNavigationEntry(false);\n const requestTime = msToSec(navEntry ? navEntry.requestStart : 0);\n // Because performance.measure accepts arbitrary timestamps it can produce\n // spans that happen before the browser even makes a request for the page.\n //\n // An example of this is the automatically generated Next.js-before-hydration\n // spans created by the Next.js framework.\n //\n // To prevent this we will pin the start timestamp to the request start time\n // This does make duration inaccurate, so if this does happen, we will add\n // an attribute to the span\n const measureStartTimestamp = timeOrigin + Math.max(startTime, requestTime);\n const startTimeStamp = timeOrigin + startTime;\n const measureEndTimestamp = startTimeStamp + duration;\n\n const attributes: SpanAttributes = {\n [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.resource.browser.metrics',\n };\n\n if (measureStartTimestamp !== startTimeStamp) {\n attributes['sentry.browser.measure_happened_before_request'] = true;\n attributes['sentry.browser.measure_start_time'] = measureStartTimestamp;\n }\n\n // Measurements from third parties can be off, which would create invalid spans, dropping transactions in the process.\n if (measureStartTimestamp <= measureEndTimestamp) {\n startAndEndSpan(span, measureStartTimestamp, measureEndTimestamp, {\n name: entry.name as string,\n op: entry.entryType as string,\n attributes,\n });\n }\n}\n\n/** Instrument navigation entries */\nfunction _addNavigationSpans(span: Span, entry: PerformanceNavigationTiming, timeOrigin: number): void {\n (['unloadEvent', 'redirect', 'domContentLoadedEvent', 'loadEvent', 'connect'] as const).forEach(event => {\n _addPerformanceNavigationTiming(span, entry, event, timeOrigin);\n });\n _addPerformanceNavigationTiming(span, entry, 'secureConnection', timeOrigin, 'TLS/SSL');\n _addPerformanceNavigationTiming(span, entry, 'fetch', timeOrigin, 'cache');\n _addPerformanceNavigationTiming(span, entry, 'domainLookup', timeOrigin, 'DNS');\n\n _addRequest(span, entry, timeOrigin);\n}\n\ntype StartEventName =\n | 'secureConnection'\n | 'fetch'\n | 'domainLookup'\n | 'unloadEvent'\n | 'redirect'\n | 'connect'\n | 'domContentLoadedEvent'\n | 'loadEvent';\n\ntype EndEventName =\n | 'connectEnd'\n | 'domainLookupStart'\n | 'domainLookupEnd'\n | 'unloadEventEnd'\n | 'redirectEnd'\n | 'connectEnd'\n | 'domContentLoadedEventEnd'\n | 'loadEventEnd';\n\n/** Create performance navigation related spans */\nfunction _addPerformanceNavigationTiming(\n span: Span,\n entry: PerformanceNavigationTiming,\n event: StartEventName,\n timeOrigin: number,\n name: string = event,\n): void {\n const eventEnd = _getEndPropertyNameForNavigationTiming(event) satisfies keyof PerformanceNavigationTiming;\n const end = entry[eventEnd];\n const start = entry[`${event}Start`];\n if (!start || !end) {\n return;\n }\n startAndEndSpan(span, timeOrigin + msToSec(start), timeOrigin + msToSec(end), {\n op: `browser.${name}`,\n name: entry.name,\n attributes: {\n [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.ui.browser.metrics',\n },\n });\n}\n\nfunction _getEndPropertyNameForNavigationTiming(event: StartEventName): EndEventName {\n if (event === 'secureConnection') {\n return 'connectEnd';\n }\n if (event === 'fetch') {\n return 'domainLookupStart';\n }\n return `${event}End`;\n}\n\n/** Create request and response related spans */\nfunction _addRequest(span: Span, entry: PerformanceNavigationTiming, timeOrigin: number): void {\n const requestStartTimestamp = timeOrigin + msToSec(entry.requestStart as number);\n const responseEndTimestamp = timeOrigin + msToSec(entry.responseEnd as number);\n const responseStartTimestamp = timeOrigin + msToSec(entry.responseStart as number);\n if (entry.responseEnd) {\n // It is possible that we are collecting these metrics when the page hasn't finished loading yet, for example when the HTML slowly streams in.\n // In this case, ie. when the document request hasn't finished yet, `entry.responseEnd` will be 0.\n // In order not to produce faulty spans, where the end timestamp is before the start timestamp, we will only collect\n // these spans when the responseEnd value is available. The backend (Relay) would drop the entire span if it contained faulty spans.\n startAndEndSpan(span, requestStartTimestamp, responseEndTimestamp, {\n op: 'browser.request',\n name: entry.name,\n attributes: {\n [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.ui.browser.metrics',\n },\n });\n\n startAndEndSpan(span, responseStartTimestamp, responseEndTimestamp, {\n op: 'browser.response',\n name: entry.name,\n attributes: {\n [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.ui.browser.metrics',\n },\n });\n }\n}\n\n/**\n * Create resource-related spans.\n * Exported only for tests.\n */\nexport function _addResourceSpans(\n span: Span,\n entry: PerformanceResourceTiming,\n resourceUrl: string,\n startTime: number,\n duration: number,\n timeOrigin: number,\n): void {\n // we already instrument based on fetch and xhr, so we don't need to\n // duplicate spans here.\n if (entry.initiatorType === 'xmlhttprequest' || entry.initiatorType === 'fetch') {\n return;\n }\n\n const parsedUrl = parseUrl(resourceUrl);\n\n const attributes: SpanAttributes = {\n [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.resource.browser.metrics',\n };\n setResourceEntrySizeData(attributes, entry, 'transferSize', 'http.response_transfer_size');\n setResourceEntrySizeData(attributes, entry, 'encodedBodySize', 'http.response_content_length');\n setResourceEntrySizeData(attributes, entry, 'decodedBodySize', 'http.decoded_response_content_length');\n\n // `deliveryType` is experimental and does not exist everywhere\n const deliveryType = (entry as { deliveryType?: 'cache' | 'navigational-prefetch' | '' }).deliveryType;\n if (deliveryType != null) {\n attributes['http.response_delivery_type'] = deliveryType;\n }\n\n // Types do not reflect this property yet\n const renderBlockingStatus = (entry as { renderBlockingStatus?: 'render-blocking' | 'non-render-blocking' })\n .renderBlockingStatus;\n if (renderBlockingStatus) {\n attributes['resource.render_blocking_status'] = renderBlockingStatus;\n }\n\n if (parsedUrl.protocol) {\n attributes['url.scheme'] = parsedUrl.protocol.split(':').pop(); // the protocol returned by parseUrl includes a :, but OTEL spec does not, so we remove it.\n }\n\n if (parsedUrl.host) {\n attributes['server.address'] = parsedUrl.host;\n }\n\n attributes['url.same_origin'] = resourceUrl.includes(WINDOW.location.origin);\n\n const { name, version } = extractNetworkProtocol(entry.nextHopProtocol);\n attributes['network.protocol.name'] = name;\n attributes['network.protocol.version'] = version;\n\n const startTimestamp = timeOrigin + startTime;\n const endTimestamp = startTimestamp + duration;\n\n startAndEndSpan(span, startTimestamp, endTimestamp, {\n name: resourceUrl.replace(WINDOW.location.origin, ''),\n op: entry.initiatorType ? `resource.${entry.initiatorType}` : 'resource.other',\n attributes,\n });\n}\n\n/**\n * Capture the information of the user agent.\n */\nfunction _trackNavigator(span: Span): void {\n const navigator = WINDOW.navigator as null | (Navigator & NavigatorNetworkInformation & NavigatorDeviceMemory);\n if (!navigator) {\n return;\n }\n\n // track network connectivity\n const connection = navigator.connection;\n if (connection) {\n if (connection.effectiveType) {\n span.setAttribute('effectiveConnectionType', connection.effectiveType);\n }\n\n if (connection.type) {\n span.setAttribute('connectionType', connection.type);\n }\n\n if (isMeasurementValue(connection.rtt)) {\n _measurements['connection.rtt'] = { value: connection.rtt, unit: 'millisecond' };\n }\n }\n\n if (isMeasurementValue(navigator.deviceMemory)) {\n span.setAttribute('deviceMemory', `${navigator.deviceMemory} GB`);\n }\n\n if (isMeasurementValue(navigator.hardwareConcurrency)) {\n span.setAttribute('hardwareConcurrency', String(navigator.hardwareConcurrency));\n }\n}\n\n/** Add LCP / CLS data to span to allow debugging */\nfunction _setWebVitalAttributes(span: Span): void {\n if (_lcpEntry) {\n // Capture Properties of the LCP element that contributes to the LCP.\n\n if (_lcpEntry.element) {\n span.setAttribute('lcp.element', htmlTreeAsString(_lcpEntry.element));\n }\n\n if (_lcpEntry.id) {\n span.setAttribute('lcp.id', _lcpEntry.id);\n }\n\n if (_lcpEntry.url) {\n // Trim URL to the first 200 characters.\n span.setAttribute('lcp.url', _lcpEntry.url.trim().slice(0, 200));\n }\n\n if (_lcpEntry.loadTime != null) {\n // loadTime is the time of LCP that's related to receiving the LCP element response..\n span.setAttribute('lcp.loadTime', _lcpEntry.loadTime);\n }\n\n if (_lcpEntry.renderTime != null) {\n // renderTime is loadTime + rendering time\n // it's 0 if the LCP element is loaded from a 3rd party origin that doesn't send the\n // `Timing-Allow-Origin` header.\n span.setAttribute('lcp.renderTime', _lcpEntry.renderTime);\n }\n\n span.setAttribute('lcp.size', _lcpEntry.size);\n }\n\n // See: https://developer.mozilla.org/en-US/docs/Web/API/LayoutShift\n if (_clsEntry && _clsEntry.sources) {\n _clsEntry.sources.forEach((source, index) =>\n span.setAttribute(`cls.source.${index + 1}`, htmlTreeAsString(source.node)),\n );\n }\n}\n\nfunction setResourceEntrySizeData(\n attributes: SpanAttributes,\n entry: PerformanceResourceTiming,\n key: keyof Pick<PerformanceResourceTiming, 'transferSize' | 'encodedBodySize' | 'decodedBodySize'>,\n dataKey: 'http.response_transfer_size' | 'http.response_content_length' | 'http.decoded_response_content_length',\n): void {\n const entryVal = entry[key];\n if (entryVal != null && entryVal < MAX_INT_AS_BYTES) {\n attributes[dataKey] = entryVal;\n }\n}\n\n/**\n * Add ttfb request time information to measurements.\n *\n * ttfb information is added via vendored web vitals library.\n */\nfunction _addTtfbRequestTimeToMeasurements(_measurements: Measurements): void {\n const navEntry = getNavigationEntry(false);\n if (!navEntry) {\n return;\n }\n\n const { responseStart, requestStart } = navEntry;\n\n if (requestStart <= responseStart) {\n _measurements['ttfb.requestTime'] = {\n value: responseStart - requestStart,\n unit: 'millisecond',\n };\n }\n}\n"],"names":["getBrowserPerformanceAPI","browserPerformanceTimeOrigin","WINDOW","trackClsAsStandaloneSpan","addPerformanceInstrumentationHandler","getActiveSpan","spanToJSON","msToSec","startAndEndSpan","SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN","htmlTreeAsString","getComponentName","addClsInstrumentationHandler","addLcpInstrumentationHandler","addFidInstrumentationHandler","addTtfbInstrumentationHandler","getVisibilityWatcher","setMeasurement","getActivationStart","getNavigationEntry","parseUrl","extractNetworkProtocol","isMeasurementValue"],"mappings":"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"} |
@@ -377,9 +377,10 @@ import { browserPerformanceTimeOrigin, getActiveSpan, spanToJSON, setMeasurement, SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN, parseUrl, htmlTreeAsString, getComponentName } from '@sentry/core'; | ||
| startAndEndSpan(span, measureStartTimestamp, measureEndTimestamp, { | ||
| name: entry.name , | ||
| op: entry.entryType , | ||
| attributes, | ||
| }); | ||
| return measureStartTimestamp; | ||
| // Measurements from third parties can be off, which would create invalid spans, dropping transactions in the process. | ||
| if (measureStartTimestamp <= measureEndTimestamp) { | ||
| startAndEndSpan(span, measureStartTimestamp, measureEndTimestamp, { | ||
| name: entry.name , | ||
| op: entry.entryType , | ||
| attributes, | ||
| }); | ||
| } | ||
| } | ||
@@ -386,0 +387,0 @@ |
@@ -1,1 +0,1 @@ | ||
| {"version":3,"file":"browserMetrics.js","sources":["../../../src/metrics/browserMetrics.ts"],"sourcesContent":["/* eslint-disable max-lines */\nimport type { Measurements, Span, SpanAttributes, StartSpanOptions } from '@sentry/core';\nimport {\n SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN,\n browserPerformanceTimeOrigin,\n getActiveSpan,\n getComponentName,\n htmlTreeAsString,\n parseUrl,\n setMeasurement,\n spanToJSON,\n} from '@sentry/core';\nimport { WINDOW } from '../types';\nimport { trackClsAsStandaloneSpan } from './cls';\nimport {\n type PerformanceLongAnimationFrameTiming,\n addClsInstrumentationHandler,\n addFidInstrumentationHandler,\n addLcpInstrumentationHandler,\n addPerformanceInstrumentationHandler,\n addTtfbInstrumentationHandler,\n} from './instrument';\nimport {\n extractNetworkProtocol,\n getBrowserPerformanceAPI,\n isMeasurementValue,\n msToSec,\n startAndEndSpan,\n} from './utils';\nimport { getActivationStart } from './web-vitals/lib/getActivationStart';\nimport { getNavigationEntry } from './web-vitals/lib/getNavigationEntry';\nimport { getVisibilityWatcher } from './web-vitals/lib/getVisibilityWatcher';\n\ninterface NavigatorNetworkInformation {\n readonly connection?: NetworkInformation;\n}\n\n// http://wicg.github.io/netinfo/#connection-types\ntype ConnectionType = 'bluetooth' | 'cellular' | 'ethernet' | 'mixed' | 'none' | 'other' | 'unknown' | 'wifi' | 'wimax';\n\n// http://wicg.github.io/netinfo/#effectiveconnectiontype-enum\ntype EffectiveConnectionType = '2g' | '3g' | '4g' | 'slow-2g';\n\n// http://wicg.github.io/netinfo/#dom-megabit\ntype Megabit = number;\n// http://wicg.github.io/netinfo/#dom-millisecond\ntype Millisecond = number;\n\n// http://wicg.github.io/netinfo/#networkinformation-interface\ninterface NetworkInformation extends EventTarget {\n // http://wicg.github.io/netinfo/#type-attribute\n readonly type?: ConnectionType;\n // http://wicg.github.io/netinfo/#effectivetype-attribute\n readonly effectiveType?: EffectiveConnectionType;\n // http://wicg.github.io/netinfo/#downlinkmax-attribute\n readonly downlinkMax?: Megabit;\n // http://wicg.github.io/netinfo/#downlink-attribute\n readonly downlink?: Megabit;\n // http://wicg.github.io/netinfo/#rtt-attribute\n readonly rtt?: Millisecond;\n // http://wicg.github.io/netinfo/#savedata-attribute\n readonly saveData?: boolean;\n // http://wicg.github.io/netinfo/#handling-changes-to-the-underlying-connection\n onchange?: EventListener;\n}\n\n// https://w3c.github.io/device-memory/#sec-device-memory-js-api\ninterface NavigatorDeviceMemory {\n readonly deviceMemory?: number;\n}\n\nconst MAX_INT_AS_BYTES = 2147483647;\n\nlet _performanceCursor: number = 0;\n\nlet _measurements: Measurements = {};\nlet _lcpEntry: LargestContentfulPaint | undefined;\nlet _clsEntry: LayoutShift | undefined;\n\ninterface StartTrackingWebVitalsOptions {\n recordClsStandaloneSpans: boolean;\n}\n\n/**\n * Start tracking web vitals.\n * The callback returned by this function can be used to stop tracking & ensure all measurements are final & captured.\n *\n * @returns A function that forces web vitals collection\n */\nexport function startTrackingWebVitals({ recordClsStandaloneSpans }: StartTrackingWebVitalsOptions): () => void {\n const performance = getBrowserPerformanceAPI();\n if (performance && browserPerformanceTimeOrigin) {\n // @ts-expect-error we want to make sure all of these are available, even if TS is sure they are\n if (performance.mark) {\n WINDOW.performance.mark('sentry-tracing-init');\n }\n const fidCleanupCallback = _trackFID();\n const lcpCleanupCallback = _trackLCP();\n const ttfbCleanupCallback = _trackTtfb();\n const clsCleanupCallback = recordClsStandaloneSpans ? trackClsAsStandaloneSpan() : _trackCLS();\n\n return (): void => {\n fidCleanupCallback();\n lcpCleanupCallback();\n ttfbCleanupCallback();\n clsCleanupCallback && clsCleanupCallback();\n };\n }\n\n return () => undefined;\n}\n\n/**\n * Start tracking long tasks.\n */\nexport function startTrackingLongTasks(): void {\n addPerformanceInstrumentationHandler('longtask', ({ entries }) => {\n const parent = getActiveSpan();\n if (!parent) {\n return;\n }\n\n const { op: parentOp, start_timestamp: parentStartTimestamp } = spanToJSON(parent);\n\n for (const entry of entries) {\n const startTime = msToSec((browserPerformanceTimeOrigin as number) + entry.startTime);\n const duration = msToSec(entry.duration);\n\n if (parentOp === 'navigation' && parentStartTimestamp && startTime < parentStartTimestamp) {\n // Skip adding a span if the long task started before the navigation started.\n // `startAndEndSpan` will otherwise adjust the parent's start time to the span's start\n // time, potentially skewing the duration of the actual navigation as reported via our\n // routing instrumentations\n continue;\n }\n\n startAndEndSpan(parent, startTime, startTime + duration, {\n name: 'Main UI thread blocked',\n op: 'ui.long-task',\n attributes: {\n [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.ui.browser.metrics',\n },\n });\n }\n });\n}\n\n/**\n * Start tracking long animation frames.\n */\nexport function startTrackingLongAnimationFrames(): void {\n // NOTE: the current web-vitals version (3.5.2) does not support long-animation-frame, so\n // we directly observe `long-animation-frame` events instead of through the web-vitals\n // `observe` helper function.\n const observer = new PerformanceObserver(list => {\n const parent = getActiveSpan();\n if (!parent) {\n return;\n }\n for (const entry of list.getEntries() as PerformanceLongAnimationFrameTiming[]) {\n if (!entry.scripts[0]) {\n continue;\n }\n\n const startTime = msToSec((browserPerformanceTimeOrigin as number) + entry.startTime);\n\n const { start_timestamp: parentStartTimestamp, op: parentOp } = spanToJSON(parent);\n\n if (parentOp === 'navigation' && parentStartTimestamp && startTime < parentStartTimestamp) {\n // Skip adding the span if the long animation frame started before the navigation started.\n // `startAndEndSpan` will otherwise adjust the parent's start time to the span's start\n // time, potentially skewing the duration of the actual navigation as reported via our\n // routing instrumentations\n continue;\n }\n\n const duration = msToSec(entry.duration);\n\n const attributes: SpanAttributes = {\n [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.ui.browser.metrics',\n };\n\n const initialScript = entry.scripts[0];\n const { invoker, invokerType, sourceURL, sourceFunctionName, sourceCharPosition } = initialScript;\n attributes['browser.script.invoker'] = invoker;\n attributes['browser.script.invoker_type'] = invokerType;\n if (sourceURL) {\n attributes['code.filepath'] = sourceURL;\n }\n if (sourceFunctionName) {\n attributes['code.function'] = sourceFunctionName;\n }\n if (sourceCharPosition !== -1) {\n attributes['browser.script.source_char_position'] = sourceCharPosition;\n }\n\n startAndEndSpan(parent, startTime, startTime + duration, {\n name: 'Main UI thread blocked',\n op: 'ui.long-animation-frame',\n attributes,\n });\n }\n });\n\n observer.observe({ type: 'long-animation-frame', buffered: true });\n}\n\n/**\n * Start tracking interaction events.\n */\nexport function startTrackingInteractions(): void {\n addPerformanceInstrumentationHandler('event', ({ entries }) => {\n const parent = getActiveSpan();\n if (!parent) {\n return;\n }\n for (const entry of entries) {\n if (entry.name === 'click') {\n const startTime = msToSec((browserPerformanceTimeOrigin as number) + entry.startTime);\n const duration = msToSec(entry.duration);\n\n const spanOptions: StartSpanOptions & Required<Pick<StartSpanOptions, 'attributes'>> = {\n name: htmlTreeAsString(entry.target),\n op: `ui.interaction.${entry.name}`,\n startTime: startTime,\n attributes: {\n [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.ui.browser.metrics',\n },\n };\n\n const componentName = getComponentName(entry.target);\n if (componentName) {\n spanOptions.attributes['ui.component_name'] = componentName;\n }\n\n startAndEndSpan(parent, startTime, startTime + duration, spanOptions);\n }\n }\n });\n}\n\nexport { registerInpInteractionListener, startTrackingINP } from './inp';\n\n/**\n * Starts tracking the Cumulative Layout Shift on the current page and collects the value and last entry\n * to the `_measurements` object which ultimately is applied to the pageload span's measurements.\n */\nfunction _trackCLS(): () => void {\n return addClsInstrumentationHandler(({ metric }) => {\n const entry = metric.entries[metric.entries.length - 1] as LayoutShift | undefined;\n if (!entry) {\n return;\n }\n _measurements['cls'] = { value: metric.value, unit: '' };\n _clsEntry = entry;\n }, true);\n}\n\n/** Starts tracking the Largest Contentful Paint on the current page. */\nfunction _trackLCP(): () => void {\n return addLcpInstrumentationHandler(({ metric }) => {\n const entry = metric.entries[metric.entries.length - 1];\n if (!entry) {\n return;\n }\n\n _measurements['lcp'] = { value: metric.value, unit: 'millisecond' };\n _lcpEntry = entry as LargestContentfulPaint;\n }, true);\n}\n\n/** Starts tracking the First Input Delay on the current page. */\nfunction _trackFID(): () => void {\n return addFidInstrumentationHandler(({ metric }) => {\n const entry = metric.entries[metric.entries.length - 1];\n if (!entry) {\n return;\n }\n\n const timeOrigin = msToSec(browserPerformanceTimeOrigin as number);\n const startTime = msToSec(entry.startTime);\n _measurements['fid'] = { value: metric.value, unit: 'millisecond' };\n _measurements['mark.fid'] = { value: timeOrigin + startTime, unit: 'second' };\n });\n}\n\nfunction _trackTtfb(): () => void {\n return addTtfbInstrumentationHandler(({ metric }) => {\n const entry = metric.entries[metric.entries.length - 1];\n if (!entry) {\n return;\n }\n\n _measurements['ttfb'] = { value: metric.value, unit: 'millisecond' };\n });\n}\n\ninterface AddPerformanceEntriesOptions {\n /**\n * Flag to determine if CLS should be recorded as a measurement on the span or\n * sent as a standalone span instead.\n */\n recordClsOnPageloadSpan: boolean;\n}\n\n/** Add performance related spans to a transaction */\nexport function addPerformanceEntries(span: Span, options: AddPerformanceEntriesOptions): void {\n const performance = getBrowserPerformanceAPI();\n if (!performance || !performance.getEntries || !browserPerformanceTimeOrigin) {\n // Gatekeeper if performance API not available\n return;\n }\n\n const timeOrigin = msToSec(browserPerformanceTimeOrigin);\n\n const performanceEntries = performance.getEntries();\n\n const { op, start_timestamp: transactionStartTime } = spanToJSON(span);\n\n performanceEntries.slice(_performanceCursor).forEach(entry => {\n const startTime = msToSec(entry.startTime);\n const duration = msToSec(\n // Inexplicably, Chrome sometimes emits a negative duration. We need to work around this.\n // There is a SO post attempting to explain this, but it leaves one with open questions: https://stackoverflow.com/questions/23191918/peformance-getentries-and-negative-duration-display\n // The way we clamp the value is probably not accurate, since we have observed this happen for things that may take a while to load, like for example the replay worker.\n // TODO: Investigate why this happens and how to properly mitigate. For now, this is a workaround to prevent transactions being dropped due to negative duration spans.\n Math.max(0, entry.duration),\n );\n\n if (op === 'navigation' && transactionStartTime && timeOrigin + startTime < transactionStartTime) {\n return;\n }\n\n switch (entry.entryType) {\n case 'navigation': {\n _addNavigationSpans(span, entry as PerformanceNavigationTiming, timeOrigin);\n break;\n }\n case 'mark':\n case 'paint':\n case 'measure': {\n _addMeasureSpans(span, entry, startTime, duration, timeOrigin);\n\n // capture web vitals\n const firstHidden = getVisibilityWatcher();\n // Only report if the page wasn't hidden prior to the web vital.\n const shouldRecord = entry.startTime < firstHidden.firstHiddenTime;\n\n if (entry.name === 'first-paint' && shouldRecord) {\n _measurements['fp'] = { value: entry.startTime, unit: 'millisecond' };\n }\n if (entry.name === 'first-contentful-paint' && shouldRecord) {\n _measurements['fcp'] = { value: entry.startTime, unit: 'millisecond' };\n }\n break;\n }\n case 'resource': {\n _addResourceSpans(span, entry as PerformanceResourceTiming, entry.name, startTime, duration, timeOrigin);\n break;\n }\n // Ignore other entry types.\n }\n });\n\n _performanceCursor = Math.max(performanceEntries.length - 1, 0);\n\n _trackNavigator(span);\n\n // Measurements are only available for pageload transactions\n if (op === 'pageload') {\n _addTtfbRequestTimeToMeasurements(_measurements);\n\n const fidMark = _measurements['mark.fid'];\n if (fidMark && _measurements['fid']) {\n // create span for FID\n startAndEndSpan(span, fidMark.value, fidMark.value + msToSec(_measurements['fid'].value), {\n name: 'first input delay',\n op: 'ui.action',\n attributes: {\n [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.ui.browser.metrics',\n },\n });\n\n // Delete mark.fid as we don't want it to be part of final payload\n delete _measurements['mark.fid'];\n }\n\n // If FCP is not recorded we should not record the cls value\n // according to the new definition of CLS.\n // TODO: Check if the first condition is still necessary: `onCLS` already only fires once `onFCP` was called.\n if (!('fcp' in _measurements) || !options.recordClsOnPageloadSpan) {\n delete _measurements.cls;\n }\n\n Object.entries(_measurements).forEach(([measurementName, measurement]) => {\n setMeasurement(measurementName, measurement.value, measurement.unit);\n });\n\n // Set timeOrigin which denotes the timestamp which to base the LCP/FCP/FP/TTFB measurements on\n span.setAttribute('performance.timeOrigin', timeOrigin);\n\n // In prerendering scenarios, where a page might be prefetched and pre-rendered before the user clicks the link,\n // the navigation starts earlier than when the user clicks it. Web Vitals should always be based on the\n // user-perceived time, so they are not reported from the actual start of the navigation, but rather from the\n // time where the user actively started the navigation, for example by clicking a link.\n // This is user action is called \"activation\" and the time between navigation and activation is stored in\n // the `activationStart` attribute of the \"navigation\" PerformanceEntry.\n span.setAttribute('performance.activationStart', getActivationStart());\n\n _setWebVitalAttributes(span);\n }\n\n _lcpEntry = undefined;\n _clsEntry = undefined;\n _measurements = {};\n}\n\n/**\n * Create measure related spans.\n * Exported only for tests.\n */\nexport function _addMeasureSpans(\n span: Span,\n entry: PerformanceEntry,\n startTime: number,\n duration: number,\n timeOrigin: number,\n): number {\n const navEntry = getNavigationEntry(false);\n const requestTime = msToSec(navEntry ? navEntry.requestStart : 0);\n // Because performance.measure accepts arbitrary timestamps it can produce\n // spans that happen before the browser even makes a request for the page.\n //\n // An example of this is the automatically generated Next.js-before-hydration\n // spans created by the Next.js framework.\n //\n // To prevent this we will pin the start timestamp to the request start time\n // This does make duration inaccurate, so if this does happen, we will add\n // an attribute to the span\n const measureStartTimestamp = timeOrigin + Math.max(startTime, requestTime);\n const startTimeStamp = timeOrigin + startTime;\n const measureEndTimestamp = startTimeStamp + duration;\n\n const attributes: SpanAttributes = {\n [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.resource.browser.metrics',\n };\n\n if (measureStartTimestamp !== startTimeStamp) {\n attributes['sentry.browser.measure_happened_before_request'] = true;\n attributes['sentry.browser.measure_start_time'] = measureStartTimestamp;\n }\n\n startAndEndSpan(span, measureStartTimestamp, measureEndTimestamp, {\n name: entry.name as string,\n op: entry.entryType as string,\n attributes,\n });\n\n return measureStartTimestamp;\n}\n\n/** Instrument navigation entries */\nfunction _addNavigationSpans(span: Span, entry: PerformanceNavigationTiming, timeOrigin: number): void {\n (['unloadEvent', 'redirect', 'domContentLoadedEvent', 'loadEvent', 'connect'] as const).forEach(event => {\n _addPerformanceNavigationTiming(span, entry, event, timeOrigin);\n });\n _addPerformanceNavigationTiming(span, entry, 'secureConnection', timeOrigin, 'TLS/SSL');\n _addPerformanceNavigationTiming(span, entry, 'fetch', timeOrigin, 'cache');\n _addPerformanceNavigationTiming(span, entry, 'domainLookup', timeOrigin, 'DNS');\n\n _addRequest(span, entry, timeOrigin);\n}\n\ntype StartEventName =\n | 'secureConnection'\n | 'fetch'\n | 'domainLookup'\n | 'unloadEvent'\n | 'redirect'\n | 'connect'\n | 'domContentLoadedEvent'\n | 'loadEvent';\n\ntype EndEventName =\n | 'connectEnd'\n | 'domainLookupStart'\n | 'domainLookupEnd'\n | 'unloadEventEnd'\n | 'redirectEnd'\n | 'connectEnd'\n | 'domContentLoadedEventEnd'\n | 'loadEventEnd';\n\n/** Create performance navigation related spans */\nfunction _addPerformanceNavigationTiming(\n span: Span,\n entry: PerformanceNavigationTiming,\n event: StartEventName,\n timeOrigin: number,\n name: string = event,\n): void {\n const eventEnd = _getEndPropertyNameForNavigationTiming(event) satisfies keyof PerformanceNavigationTiming;\n const end = entry[eventEnd];\n const start = entry[`${event}Start`];\n if (!start || !end) {\n return;\n }\n startAndEndSpan(span, timeOrigin + msToSec(start), timeOrigin + msToSec(end), {\n op: `browser.${name}`,\n name: entry.name,\n attributes: {\n [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.ui.browser.metrics',\n },\n });\n}\n\nfunction _getEndPropertyNameForNavigationTiming(event: StartEventName): EndEventName {\n if (event === 'secureConnection') {\n return 'connectEnd';\n }\n if (event === 'fetch') {\n return 'domainLookupStart';\n }\n return `${event}End`;\n}\n\n/** Create request and response related spans */\nfunction _addRequest(span: Span, entry: PerformanceNavigationTiming, timeOrigin: number): void {\n const requestStartTimestamp = timeOrigin + msToSec(entry.requestStart as number);\n const responseEndTimestamp = timeOrigin + msToSec(entry.responseEnd as number);\n const responseStartTimestamp = timeOrigin + msToSec(entry.responseStart as number);\n if (entry.responseEnd) {\n // It is possible that we are collecting these metrics when the page hasn't finished loading yet, for example when the HTML slowly streams in.\n // In this case, ie. when the document request hasn't finished yet, `entry.responseEnd` will be 0.\n // In order not to produce faulty spans, where the end timestamp is before the start timestamp, we will only collect\n // these spans when the responseEnd value is available. The backend (Relay) would drop the entire span if it contained faulty spans.\n startAndEndSpan(span, requestStartTimestamp, responseEndTimestamp, {\n op: 'browser.request',\n name: entry.name,\n attributes: {\n [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.ui.browser.metrics',\n },\n });\n\n startAndEndSpan(span, responseStartTimestamp, responseEndTimestamp, {\n op: 'browser.response',\n name: entry.name,\n attributes: {\n [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.ui.browser.metrics',\n },\n });\n }\n}\n\n/**\n * Create resource-related spans.\n * Exported only for tests.\n */\nexport function _addResourceSpans(\n span: Span,\n entry: PerformanceResourceTiming,\n resourceUrl: string,\n startTime: number,\n duration: number,\n timeOrigin: number,\n): void {\n // we already instrument based on fetch and xhr, so we don't need to\n // duplicate spans here.\n if (entry.initiatorType === 'xmlhttprequest' || entry.initiatorType === 'fetch') {\n return;\n }\n\n const parsedUrl = parseUrl(resourceUrl);\n\n const attributes: SpanAttributes = {\n [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.resource.browser.metrics',\n };\n setResourceEntrySizeData(attributes, entry, 'transferSize', 'http.response_transfer_size');\n setResourceEntrySizeData(attributes, entry, 'encodedBodySize', 'http.response_content_length');\n setResourceEntrySizeData(attributes, entry, 'decodedBodySize', 'http.decoded_response_content_length');\n\n // `deliveryType` is experimental and does not exist everywhere\n const deliveryType = (entry as { deliveryType?: 'cache' | 'navigational-prefetch' | '' }).deliveryType;\n if (deliveryType != null) {\n attributes['http.response_delivery_type'] = deliveryType;\n }\n\n // Types do not reflect this property yet\n const renderBlockingStatus = (entry as { renderBlockingStatus?: 'render-blocking' | 'non-render-blocking' })\n .renderBlockingStatus;\n if (renderBlockingStatus) {\n attributes['resource.render_blocking_status'] = renderBlockingStatus;\n }\n\n if (parsedUrl.protocol) {\n attributes['url.scheme'] = parsedUrl.protocol.split(':').pop(); // the protocol returned by parseUrl includes a :, but OTEL spec does not, so we remove it.\n }\n\n if (parsedUrl.host) {\n attributes['server.address'] = parsedUrl.host;\n }\n\n attributes['url.same_origin'] = resourceUrl.includes(WINDOW.location.origin);\n\n const { name, version } = extractNetworkProtocol(entry.nextHopProtocol);\n attributes['network.protocol.name'] = name;\n attributes['network.protocol.version'] = version;\n\n const startTimestamp = timeOrigin + startTime;\n const endTimestamp = startTimestamp + duration;\n\n startAndEndSpan(span, startTimestamp, endTimestamp, {\n name: resourceUrl.replace(WINDOW.location.origin, ''),\n op: entry.initiatorType ? `resource.${entry.initiatorType}` : 'resource.other',\n attributes,\n });\n}\n\n/**\n * Capture the information of the user agent.\n */\nfunction _trackNavigator(span: Span): void {\n const navigator = WINDOW.navigator as null | (Navigator & NavigatorNetworkInformation & NavigatorDeviceMemory);\n if (!navigator) {\n return;\n }\n\n // track network connectivity\n const connection = navigator.connection;\n if (connection) {\n if (connection.effectiveType) {\n span.setAttribute('effectiveConnectionType', connection.effectiveType);\n }\n\n if (connection.type) {\n span.setAttribute('connectionType', connection.type);\n }\n\n if (isMeasurementValue(connection.rtt)) {\n _measurements['connection.rtt'] = { value: connection.rtt, unit: 'millisecond' };\n }\n }\n\n if (isMeasurementValue(navigator.deviceMemory)) {\n span.setAttribute('deviceMemory', `${navigator.deviceMemory} GB`);\n }\n\n if (isMeasurementValue(navigator.hardwareConcurrency)) {\n span.setAttribute('hardwareConcurrency', String(navigator.hardwareConcurrency));\n }\n}\n\n/** Add LCP / CLS data to span to allow debugging */\nfunction _setWebVitalAttributes(span: Span): void {\n if (_lcpEntry) {\n // Capture Properties of the LCP element that contributes to the LCP.\n\n if (_lcpEntry.element) {\n span.setAttribute('lcp.element', htmlTreeAsString(_lcpEntry.element));\n }\n\n if (_lcpEntry.id) {\n span.setAttribute('lcp.id', _lcpEntry.id);\n }\n\n if (_lcpEntry.url) {\n // Trim URL to the first 200 characters.\n span.setAttribute('lcp.url', _lcpEntry.url.trim().slice(0, 200));\n }\n\n if (_lcpEntry.loadTime != null) {\n // loadTime is the time of LCP that's related to receiving the LCP element response..\n span.setAttribute('lcp.loadTime', _lcpEntry.loadTime);\n }\n\n if (_lcpEntry.renderTime != null) {\n // renderTime is loadTime + rendering time\n // it's 0 if the LCP element is loaded from a 3rd party origin that doesn't send the\n // `Timing-Allow-Origin` header.\n span.setAttribute('lcp.renderTime', _lcpEntry.renderTime);\n }\n\n span.setAttribute('lcp.size', _lcpEntry.size);\n }\n\n // See: https://developer.mozilla.org/en-US/docs/Web/API/LayoutShift\n if (_clsEntry && _clsEntry.sources) {\n _clsEntry.sources.forEach((source, index) =>\n span.setAttribute(`cls.source.${index + 1}`, htmlTreeAsString(source.node)),\n );\n }\n}\n\nfunction setResourceEntrySizeData(\n attributes: SpanAttributes,\n entry: PerformanceResourceTiming,\n key: keyof Pick<PerformanceResourceTiming, 'transferSize' | 'encodedBodySize' | 'decodedBodySize'>,\n dataKey: 'http.response_transfer_size' | 'http.response_content_length' | 'http.decoded_response_content_length',\n): void {\n const entryVal = entry[key];\n if (entryVal != null && entryVal < MAX_INT_AS_BYTES) {\n attributes[dataKey] = entryVal;\n }\n}\n\n/**\n * Add ttfb request time information to measurements.\n *\n * ttfb information is added via vendored web vitals library.\n */\nfunction _addTtfbRequestTimeToMeasurements(_measurements: Measurements): void {\n const navEntry = getNavigationEntry(false);\n if (!navEntry) {\n return;\n }\n\n const { responseStart, requestStart } = navEntry;\n\n if (requestStart <= responseStart) {\n _measurements['ttfb.requestTime'] = {\n value: responseStart - requestStart,\n unit: 'millisecond',\n };\n }\n}\n"],"names":[],"mappings":"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"} | ||
| {"version":3,"file":"browserMetrics.js","sources":["../../../src/metrics/browserMetrics.ts"],"sourcesContent":["/* eslint-disable max-lines */\nimport type { Measurements, Span, SpanAttributes, StartSpanOptions } from '@sentry/core';\nimport {\n SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN,\n browserPerformanceTimeOrigin,\n getActiveSpan,\n getComponentName,\n htmlTreeAsString,\n parseUrl,\n setMeasurement,\n spanToJSON,\n} from '@sentry/core';\nimport { WINDOW } from '../types';\nimport { trackClsAsStandaloneSpan } from './cls';\nimport {\n type PerformanceLongAnimationFrameTiming,\n addClsInstrumentationHandler,\n addFidInstrumentationHandler,\n addLcpInstrumentationHandler,\n addPerformanceInstrumentationHandler,\n addTtfbInstrumentationHandler,\n} from './instrument';\nimport {\n extractNetworkProtocol,\n getBrowserPerformanceAPI,\n isMeasurementValue,\n msToSec,\n startAndEndSpan,\n} from './utils';\nimport { getActivationStart } from './web-vitals/lib/getActivationStart';\nimport { getNavigationEntry } from './web-vitals/lib/getNavigationEntry';\nimport { getVisibilityWatcher } from './web-vitals/lib/getVisibilityWatcher';\n\ninterface NavigatorNetworkInformation {\n readonly connection?: NetworkInformation;\n}\n\n// http://wicg.github.io/netinfo/#connection-types\ntype ConnectionType = 'bluetooth' | 'cellular' | 'ethernet' | 'mixed' | 'none' | 'other' | 'unknown' | 'wifi' | 'wimax';\n\n// http://wicg.github.io/netinfo/#effectiveconnectiontype-enum\ntype EffectiveConnectionType = '2g' | '3g' | '4g' | 'slow-2g';\n\n// http://wicg.github.io/netinfo/#dom-megabit\ntype Megabit = number;\n// http://wicg.github.io/netinfo/#dom-millisecond\ntype Millisecond = number;\n\n// http://wicg.github.io/netinfo/#networkinformation-interface\ninterface NetworkInformation extends EventTarget {\n // http://wicg.github.io/netinfo/#type-attribute\n readonly type?: ConnectionType;\n // http://wicg.github.io/netinfo/#effectivetype-attribute\n readonly effectiveType?: EffectiveConnectionType;\n // http://wicg.github.io/netinfo/#downlinkmax-attribute\n readonly downlinkMax?: Megabit;\n // http://wicg.github.io/netinfo/#downlink-attribute\n readonly downlink?: Megabit;\n // http://wicg.github.io/netinfo/#rtt-attribute\n readonly rtt?: Millisecond;\n // http://wicg.github.io/netinfo/#savedata-attribute\n readonly saveData?: boolean;\n // http://wicg.github.io/netinfo/#handling-changes-to-the-underlying-connection\n onchange?: EventListener;\n}\n\n// https://w3c.github.io/device-memory/#sec-device-memory-js-api\ninterface NavigatorDeviceMemory {\n readonly deviceMemory?: number;\n}\n\nconst MAX_INT_AS_BYTES = 2147483647;\n\nlet _performanceCursor: number = 0;\n\nlet _measurements: Measurements = {};\nlet _lcpEntry: LargestContentfulPaint | undefined;\nlet _clsEntry: LayoutShift | undefined;\n\ninterface StartTrackingWebVitalsOptions {\n recordClsStandaloneSpans: boolean;\n}\n\n/**\n * Start tracking web vitals.\n * The callback returned by this function can be used to stop tracking & ensure all measurements are final & captured.\n *\n * @returns A function that forces web vitals collection\n */\nexport function startTrackingWebVitals({ recordClsStandaloneSpans }: StartTrackingWebVitalsOptions): () => void {\n const performance = getBrowserPerformanceAPI();\n if (performance && browserPerformanceTimeOrigin) {\n // @ts-expect-error we want to make sure all of these are available, even if TS is sure they are\n if (performance.mark) {\n WINDOW.performance.mark('sentry-tracing-init');\n }\n const fidCleanupCallback = _trackFID();\n const lcpCleanupCallback = _trackLCP();\n const ttfbCleanupCallback = _trackTtfb();\n const clsCleanupCallback = recordClsStandaloneSpans ? trackClsAsStandaloneSpan() : _trackCLS();\n\n return (): void => {\n fidCleanupCallback();\n lcpCleanupCallback();\n ttfbCleanupCallback();\n clsCleanupCallback && clsCleanupCallback();\n };\n }\n\n return () => undefined;\n}\n\n/**\n * Start tracking long tasks.\n */\nexport function startTrackingLongTasks(): void {\n addPerformanceInstrumentationHandler('longtask', ({ entries }) => {\n const parent = getActiveSpan();\n if (!parent) {\n return;\n }\n\n const { op: parentOp, start_timestamp: parentStartTimestamp } = spanToJSON(parent);\n\n for (const entry of entries) {\n const startTime = msToSec((browserPerformanceTimeOrigin as number) + entry.startTime);\n const duration = msToSec(entry.duration);\n\n if (parentOp === 'navigation' && parentStartTimestamp && startTime < parentStartTimestamp) {\n // Skip adding a span if the long task started before the navigation started.\n // `startAndEndSpan` will otherwise adjust the parent's start time to the span's start\n // time, potentially skewing the duration of the actual navigation as reported via our\n // routing instrumentations\n continue;\n }\n\n startAndEndSpan(parent, startTime, startTime + duration, {\n name: 'Main UI thread blocked',\n op: 'ui.long-task',\n attributes: {\n [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.ui.browser.metrics',\n },\n });\n }\n });\n}\n\n/**\n * Start tracking long animation frames.\n */\nexport function startTrackingLongAnimationFrames(): void {\n // NOTE: the current web-vitals version (3.5.2) does not support long-animation-frame, so\n // we directly observe `long-animation-frame` events instead of through the web-vitals\n // `observe` helper function.\n const observer = new PerformanceObserver(list => {\n const parent = getActiveSpan();\n if (!parent) {\n return;\n }\n for (const entry of list.getEntries() as PerformanceLongAnimationFrameTiming[]) {\n if (!entry.scripts[0]) {\n continue;\n }\n\n const startTime = msToSec((browserPerformanceTimeOrigin as number) + entry.startTime);\n\n const { start_timestamp: parentStartTimestamp, op: parentOp } = spanToJSON(parent);\n\n if (parentOp === 'navigation' && parentStartTimestamp && startTime < parentStartTimestamp) {\n // Skip adding the span if the long animation frame started before the navigation started.\n // `startAndEndSpan` will otherwise adjust the parent's start time to the span's start\n // time, potentially skewing the duration of the actual navigation as reported via our\n // routing instrumentations\n continue;\n }\n\n const duration = msToSec(entry.duration);\n\n const attributes: SpanAttributes = {\n [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.ui.browser.metrics',\n };\n\n const initialScript = entry.scripts[0];\n const { invoker, invokerType, sourceURL, sourceFunctionName, sourceCharPosition } = initialScript;\n attributes['browser.script.invoker'] = invoker;\n attributes['browser.script.invoker_type'] = invokerType;\n if (sourceURL) {\n attributes['code.filepath'] = sourceURL;\n }\n if (sourceFunctionName) {\n attributes['code.function'] = sourceFunctionName;\n }\n if (sourceCharPosition !== -1) {\n attributes['browser.script.source_char_position'] = sourceCharPosition;\n }\n\n startAndEndSpan(parent, startTime, startTime + duration, {\n name: 'Main UI thread blocked',\n op: 'ui.long-animation-frame',\n attributes,\n });\n }\n });\n\n observer.observe({ type: 'long-animation-frame', buffered: true });\n}\n\n/**\n * Start tracking interaction events.\n */\nexport function startTrackingInteractions(): void {\n addPerformanceInstrumentationHandler('event', ({ entries }) => {\n const parent = getActiveSpan();\n if (!parent) {\n return;\n }\n for (const entry of entries) {\n if (entry.name === 'click') {\n const startTime = msToSec((browserPerformanceTimeOrigin as number) + entry.startTime);\n const duration = msToSec(entry.duration);\n\n const spanOptions: StartSpanOptions & Required<Pick<StartSpanOptions, 'attributes'>> = {\n name: htmlTreeAsString(entry.target),\n op: `ui.interaction.${entry.name}`,\n startTime: startTime,\n attributes: {\n [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.ui.browser.metrics',\n },\n };\n\n const componentName = getComponentName(entry.target);\n if (componentName) {\n spanOptions.attributes['ui.component_name'] = componentName;\n }\n\n startAndEndSpan(parent, startTime, startTime + duration, spanOptions);\n }\n }\n });\n}\n\nexport { registerInpInteractionListener, startTrackingINP } from './inp';\n\n/**\n * Starts tracking the Cumulative Layout Shift on the current page and collects the value and last entry\n * to the `_measurements` object which ultimately is applied to the pageload span's measurements.\n */\nfunction _trackCLS(): () => void {\n return addClsInstrumentationHandler(({ metric }) => {\n const entry = metric.entries[metric.entries.length - 1] as LayoutShift | undefined;\n if (!entry) {\n return;\n }\n _measurements['cls'] = { value: metric.value, unit: '' };\n _clsEntry = entry;\n }, true);\n}\n\n/** Starts tracking the Largest Contentful Paint on the current page. */\nfunction _trackLCP(): () => void {\n return addLcpInstrumentationHandler(({ metric }) => {\n const entry = metric.entries[metric.entries.length - 1];\n if (!entry) {\n return;\n }\n\n _measurements['lcp'] = { value: metric.value, unit: 'millisecond' };\n _lcpEntry = entry as LargestContentfulPaint;\n }, true);\n}\n\n/** Starts tracking the First Input Delay on the current page. */\nfunction _trackFID(): () => void {\n return addFidInstrumentationHandler(({ metric }) => {\n const entry = metric.entries[metric.entries.length - 1];\n if (!entry) {\n return;\n }\n\n const timeOrigin = msToSec(browserPerformanceTimeOrigin as number);\n const startTime = msToSec(entry.startTime);\n _measurements['fid'] = { value: metric.value, unit: 'millisecond' };\n _measurements['mark.fid'] = { value: timeOrigin + startTime, unit: 'second' };\n });\n}\n\nfunction _trackTtfb(): () => void {\n return addTtfbInstrumentationHandler(({ metric }) => {\n const entry = metric.entries[metric.entries.length - 1];\n if (!entry) {\n return;\n }\n\n _measurements['ttfb'] = { value: metric.value, unit: 'millisecond' };\n });\n}\n\ninterface AddPerformanceEntriesOptions {\n /**\n * Flag to determine if CLS should be recorded as a measurement on the span or\n * sent as a standalone span instead.\n */\n recordClsOnPageloadSpan: boolean;\n}\n\n/** Add performance related spans to a transaction */\nexport function addPerformanceEntries(span: Span, options: AddPerformanceEntriesOptions): void {\n const performance = getBrowserPerformanceAPI();\n if (!performance || !performance.getEntries || !browserPerformanceTimeOrigin) {\n // Gatekeeper if performance API not available\n return;\n }\n\n const timeOrigin = msToSec(browserPerformanceTimeOrigin);\n\n const performanceEntries = performance.getEntries();\n\n const { op, start_timestamp: transactionStartTime } = spanToJSON(span);\n\n performanceEntries.slice(_performanceCursor).forEach(entry => {\n const startTime = msToSec(entry.startTime);\n const duration = msToSec(\n // Inexplicably, Chrome sometimes emits a negative duration. We need to work around this.\n // There is a SO post attempting to explain this, but it leaves one with open questions: https://stackoverflow.com/questions/23191918/peformance-getentries-and-negative-duration-display\n // The way we clamp the value is probably not accurate, since we have observed this happen for things that may take a while to load, like for example the replay worker.\n // TODO: Investigate why this happens and how to properly mitigate. For now, this is a workaround to prevent transactions being dropped due to negative duration spans.\n Math.max(0, entry.duration),\n );\n\n if (op === 'navigation' && transactionStartTime && timeOrigin + startTime < transactionStartTime) {\n return;\n }\n\n switch (entry.entryType) {\n case 'navigation': {\n _addNavigationSpans(span, entry as PerformanceNavigationTiming, timeOrigin);\n break;\n }\n case 'mark':\n case 'paint':\n case 'measure': {\n _addMeasureSpans(span, entry, startTime, duration, timeOrigin);\n\n // capture web vitals\n const firstHidden = getVisibilityWatcher();\n // Only report if the page wasn't hidden prior to the web vital.\n const shouldRecord = entry.startTime < firstHidden.firstHiddenTime;\n\n if (entry.name === 'first-paint' && shouldRecord) {\n _measurements['fp'] = { value: entry.startTime, unit: 'millisecond' };\n }\n if (entry.name === 'first-contentful-paint' && shouldRecord) {\n _measurements['fcp'] = { value: entry.startTime, unit: 'millisecond' };\n }\n break;\n }\n case 'resource': {\n _addResourceSpans(span, entry as PerformanceResourceTiming, entry.name, startTime, duration, timeOrigin);\n break;\n }\n // Ignore other entry types.\n }\n });\n\n _performanceCursor = Math.max(performanceEntries.length - 1, 0);\n\n _trackNavigator(span);\n\n // Measurements are only available for pageload transactions\n if (op === 'pageload') {\n _addTtfbRequestTimeToMeasurements(_measurements);\n\n const fidMark = _measurements['mark.fid'];\n if (fidMark && _measurements['fid']) {\n // create span for FID\n startAndEndSpan(span, fidMark.value, fidMark.value + msToSec(_measurements['fid'].value), {\n name: 'first input delay',\n op: 'ui.action',\n attributes: {\n [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.ui.browser.metrics',\n },\n });\n\n // Delete mark.fid as we don't want it to be part of final payload\n delete _measurements['mark.fid'];\n }\n\n // If FCP is not recorded we should not record the cls value\n // according to the new definition of CLS.\n // TODO: Check if the first condition is still necessary: `onCLS` already only fires once `onFCP` was called.\n if (!('fcp' in _measurements) || !options.recordClsOnPageloadSpan) {\n delete _measurements.cls;\n }\n\n Object.entries(_measurements).forEach(([measurementName, measurement]) => {\n setMeasurement(measurementName, measurement.value, measurement.unit);\n });\n\n // Set timeOrigin which denotes the timestamp which to base the LCP/FCP/FP/TTFB measurements on\n span.setAttribute('performance.timeOrigin', timeOrigin);\n\n // In prerendering scenarios, where a page might be prefetched and pre-rendered before the user clicks the link,\n // the navigation starts earlier than when the user clicks it. Web Vitals should always be based on the\n // user-perceived time, so they are not reported from the actual start of the navigation, but rather from the\n // time where the user actively started the navigation, for example by clicking a link.\n // This is user action is called \"activation\" and the time between navigation and activation is stored in\n // the `activationStart` attribute of the \"navigation\" PerformanceEntry.\n span.setAttribute('performance.activationStart', getActivationStart());\n\n _setWebVitalAttributes(span);\n }\n\n _lcpEntry = undefined;\n _clsEntry = undefined;\n _measurements = {};\n}\n\n/**\n * Create measure related spans.\n * Exported only for tests.\n */\nexport function _addMeasureSpans(\n span: Span,\n entry: PerformanceEntry,\n startTime: number,\n duration: number,\n timeOrigin: number,\n): void {\n const navEntry = getNavigationEntry(false);\n const requestTime = msToSec(navEntry ? navEntry.requestStart : 0);\n // Because performance.measure accepts arbitrary timestamps it can produce\n // spans that happen before the browser even makes a request for the page.\n //\n // An example of this is the automatically generated Next.js-before-hydration\n // spans created by the Next.js framework.\n //\n // To prevent this we will pin the start timestamp to the request start time\n // This does make duration inaccurate, so if this does happen, we will add\n // an attribute to the span\n const measureStartTimestamp = timeOrigin + Math.max(startTime, requestTime);\n const startTimeStamp = timeOrigin + startTime;\n const measureEndTimestamp = startTimeStamp + duration;\n\n const attributes: SpanAttributes = {\n [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.resource.browser.metrics',\n };\n\n if (measureStartTimestamp !== startTimeStamp) {\n attributes['sentry.browser.measure_happened_before_request'] = true;\n attributes['sentry.browser.measure_start_time'] = measureStartTimestamp;\n }\n\n // Measurements from third parties can be off, which would create invalid spans, dropping transactions in the process.\n if (measureStartTimestamp <= measureEndTimestamp) {\n startAndEndSpan(span, measureStartTimestamp, measureEndTimestamp, {\n name: entry.name as string,\n op: entry.entryType as string,\n attributes,\n });\n }\n}\n\n/** Instrument navigation entries */\nfunction _addNavigationSpans(span: Span, entry: PerformanceNavigationTiming, timeOrigin: number): void {\n (['unloadEvent', 'redirect', 'domContentLoadedEvent', 'loadEvent', 'connect'] as const).forEach(event => {\n _addPerformanceNavigationTiming(span, entry, event, timeOrigin);\n });\n _addPerformanceNavigationTiming(span, entry, 'secureConnection', timeOrigin, 'TLS/SSL');\n _addPerformanceNavigationTiming(span, entry, 'fetch', timeOrigin, 'cache');\n _addPerformanceNavigationTiming(span, entry, 'domainLookup', timeOrigin, 'DNS');\n\n _addRequest(span, entry, timeOrigin);\n}\n\ntype StartEventName =\n | 'secureConnection'\n | 'fetch'\n | 'domainLookup'\n | 'unloadEvent'\n | 'redirect'\n | 'connect'\n | 'domContentLoadedEvent'\n | 'loadEvent';\n\ntype EndEventName =\n | 'connectEnd'\n | 'domainLookupStart'\n | 'domainLookupEnd'\n | 'unloadEventEnd'\n | 'redirectEnd'\n | 'connectEnd'\n | 'domContentLoadedEventEnd'\n | 'loadEventEnd';\n\n/** Create performance navigation related spans */\nfunction _addPerformanceNavigationTiming(\n span: Span,\n entry: PerformanceNavigationTiming,\n event: StartEventName,\n timeOrigin: number,\n name: string = event,\n): void {\n const eventEnd = _getEndPropertyNameForNavigationTiming(event) satisfies keyof PerformanceNavigationTiming;\n const end = entry[eventEnd];\n const start = entry[`${event}Start`];\n if (!start || !end) {\n return;\n }\n startAndEndSpan(span, timeOrigin + msToSec(start), timeOrigin + msToSec(end), {\n op: `browser.${name}`,\n name: entry.name,\n attributes: {\n [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.ui.browser.metrics',\n },\n });\n}\n\nfunction _getEndPropertyNameForNavigationTiming(event: StartEventName): EndEventName {\n if (event === 'secureConnection') {\n return 'connectEnd';\n }\n if (event === 'fetch') {\n return 'domainLookupStart';\n }\n return `${event}End`;\n}\n\n/** Create request and response related spans */\nfunction _addRequest(span: Span, entry: PerformanceNavigationTiming, timeOrigin: number): void {\n const requestStartTimestamp = timeOrigin + msToSec(entry.requestStart as number);\n const responseEndTimestamp = timeOrigin + msToSec(entry.responseEnd as number);\n const responseStartTimestamp = timeOrigin + msToSec(entry.responseStart as number);\n if (entry.responseEnd) {\n // It is possible that we are collecting these metrics when the page hasn't finished loading yet, for example when the HTML slowly streams in.\n // In this case, ie. when the document request hasn't finished yet, `entry.responseEnd` will be 0.\n // In order not to produce faulty spans, where the end timestamp is before the start timestamp, we will only collect\n // these spans when the responseEnd value is available. The backend (Relay) would drop the entire span if it contained faulty spans.\n startAndEndSpan(span, requestStartTimestamp, responseEndTimestamp, {\n op: 'browser.request',\n name: entry.name,\n attributes: {\n [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.ui.browser.metrics',\n },\n });\n\n startAndEndSpan(span, responseStartTimestamp, responseEndTimestamp, {\n op: 'browser.response',\n name: entry.name,\n attributes: {\n [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.ui.browser.metrics',\n },\n });\n }\n}\n\n/**\n * Create resource-related spans.\n * Exported only for tests.\n */\nexport function _addResourceSpans(\n span: Span,\n entry: PerformanceResourceTiming,\n resourceUrl: string,\n startTime: number,\n duration: number,\n timeOrigin: number,\n): void {\n // we already instrument based on fetch and xhr, so we don't need to\n // duplicate spans here.\n if (entry.initiatorType === 'xmlhttprequest' || entry.initiatorType === 'fetch') {\n return;\n }\n\n const parsedUrl = parseUrl(resourceUrl);\n\n const attributes: SpanAttributes = {\n [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.resource.browser.metrics',\n };\n setResourceEntrySizeData(attributes, entry, 'transferSize', 'http.response_transfer_size');\n setResourceEntrySizeData(attributes, entry, 'encodedBodySize', 'http.response_content_length');\n setResourceEntrySizeData(attributes, entry, 'decodedBodySize', 'http.decoded_response_content_length');\n\n // `deliveryType` is experimental and does not exist everywhere\n const deliveryType = (entry as { deliveryType?: 'cache' | 'navigational-prefetch' | '' }).deliveryType;\n if (deliveryType != null) {\n attributes['http.response_delivery_type'] = deliveryType;\n }\n\n // Types do not reflect this property yet\n const renderBlockingStatus = (entry as { renderBlockingStatus?: 'render-blocking' | 'non-render-blocking' })\n .renderBlockingStatus;\n if (renderBlockingStatus) {\n attributes['resource.render_blocking_status'] = renderBlockingStatus;\n }\n\n if (parsedUrl.protocol) {\n attributes['url.scheme'] = parsedUrl.protocol.split(':').pop(); // the protocol returned by parseUrl includes a :, but OTEL spec does not, so we remove it.\n }\n\n if (parsedUrl.host) {\n attributes['server.address'] = parsedUrl.host;\n }\n\n attributes['url.same_origin'] = resourceUrl.includes(WINDOW.location.origin);\n\n const { name, version } = extractNetworkProtocol(entry.nextHopProtocol);\n attributes['network.protocol.name'] = name;\n attributes['network.protocol.version'] = version;\n\n const startTimestamp = timeOrigin + startTime;\n const endTimestamp = startTimestamp + duration;\n\n startAndEndSpan(span, startTimestamp, endTimestamp, {\n name: resourceUrl.replace(WINDOW.location.origin, ''),\n op: entry.initiatorType ? `resource.${entry.initiatorType}` : 'resource.other',\n attributes,\n });\n}\n\n/**\n * Capture the information of the user agent.\n */\nfunction _trackNavigator(span: Span): void {\n const navigator = WINDOW.navigator as null | (Navigator & NavigatorNetworkInformation & NavigatorDeviceMemory);\n if (!navigator) {\n return;\n }\n\n // track network connectivity\n const connection = navigator.connection;\n if (connection) {\n if (connection.effectiveType) {\n span.setAttribute('effectiveConnectionType', connection.effectiveType);\n }\n\n if (connection.type) {\n span.setAttribute('connectionType', connection.type);\n }\n\n if (isMeasurementValue(connection.rtt)) {\n _measurements['connection.rtt'] = { value: connection.rtt, unit: 'millisecond' };\n }\n }\n\n if (isMeasurementValue(navigator.deviceMemory)) {\n span.setAttribute('deviceMemory', `${navigator.deviceMemory} GB`);\n }\n\n if (isMeasurementValue(navigator.hardwareConcurrency)) {\n span.setAttribute('hardwareConcurrency', String(navigator.hardwareConcurrency));\n }\n}\n\n/** Add LCP / CLS data to span to allow debugging */\nfunction _setWebVitalAttributes(span: Span): void {\n if (_lcpEntry) {\n // Capture Properties of the LCP element that contributes to the LCP.\n\n if (_lcpEntry.element) {\n span.setAttribute('lcp.element', htmlTreeAsString(_lcpEntry.element));\n }\n\n if (_lcpEntry.id) {\n span.setAttribute('lcp.id', _lcpEntry.id);\n }\n\n if (_lcpEntry.url) {\n // Trim URL to the first 200 characters.\n span.setAttribute('lcp.url', _lcpEntry.url.trim().slice(0, 200));\n }\n\n if (_lcpEntry.loadTime != null) {\n // loadTime is the time of LCP that's related to receiving the LCP element response..\n span.setAttribute('lcp.loadTime', _lcpEntry.loadTime);\n }\n\n if (_lcpEntry.renderTime != null) {\n // renderTime is loadTime + rendering time\n // it's 0 if the LCP element is loaded from a 3rd party origin that doesn't send the\n // `Timing-Allow-Origin` header.\n span.setAttribute('lcp.renderTime', _lcpEntry.renderTime);\n }\n\n span.setAttribute('lcp.size', _lcpEntry.size);\n }\n\n // See: https://developer.mozilla.org/en-US/docs/Web/API/LayoutShift\n if (_clsEntry && _clsEntry.sources) {\n _clsEntry.sources.forEach((source, index) =>\n span.setAttribute(`cls.source.${index + 1}`, htmlTreeAsString(source.node)),\n );\n }\n}\n\nfunction setResourceEntrySizeData(\n attributes: SpanAttributes,\n entry: PerformanceResourceTiming,\n key: keyof Pick<PerformanceResourceTiming, 'transferSize' | 'encodedBodySize' | 'decodedBodySize'>,\n dataKey: 'http.response_transfer_size' | 'http.response_content_length' | 'http.decoded_response_content_length',\n): void {\n const entryVal = entry[key];\n if (entryVal != null && entryVal < MAX_INT_AS_BYTES) {\n attributes[dataKey] = entryVal;\n }\n}\n\n/**\n * Add ttfb request time information to measurements.\n *\n * ttfb information is added via vendored web vitals library.\n */\nfunction _addTtfbRequestTimeToMeasurements(_measurements: Measurements): void {\n const navEntry = getNavigationEntry(false);\n if (!navEntry) {\n return;\n }\n\n const { responseStart, requestStart } = navEntry;\n\n if (requestStart <= responseStart) {\n _measurements['ttfb.requestTime'] = {\n value: responseStart - requestStart,\n unit: 'millisecond',\n };\n }\n}\n"],"names":[],"mappings":"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"} |
@@ -1,1 +0,1 @@ | ||
| {"type":"module","version":"8.55.0","sideEffects":false} | ||
| {"type":"module","version":"8.55.1","sideEffects":false} |
@@ -38,3 +38,3 @@ import { Span } from '@sentry/core'; | ||
| */ | ||
| export declare function _addMeasureSpans(span: Span, entry: PerformanceEntry, startTime: number, duration: number, timeOrigin: number): number; | ||
| export declare function _addMeasureSpans(span: Span, entry: PerformanceEntry, startTime: number, duration: number, timeOrigin: number): void; | ||
| /** | ||
@@ -41,0 +41,0 @@ * Create resource-related spans. |
@@ -38,3 +38,3 @@ import type { Span } from '@sentry/core'; | ||
| */ | ||
| export declare function _addMeasureSpans(span: Span, entry: PerformanceEntry, startTime: number, duration: number, timeOrigin: number): number; | ||
| export declare function _addMeasureSpans(span: Span, entry: PerformanceEntry, startTime: number, duration: number, timeOrigin: number): void; | ||
| /** | ||
@@ -41,0 +41,0 @@ * Create resource-related spans. |
@@ -1,1 +0,1 @@ | ||
| {"version":3,"file":"browserMetrics.d.ts","sourceRoot":"","sources":["../../../src/metrics/browserMetrics.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAgB,IAAI,EAAoC,MAAM,cAAc,CAAC;AA8EzF,UAAU,6BAA6B;IACrC,wBAAwB,EAAE,OAAO,CAAC;CACnC;AAED;;;;;GAKG;AACH,wBAAgB,sBAAsB,CAAC,EAAE,wBAAwB,EAAE,EAAE,6BAA6B,GAAG,MAAM,IAAI,CAqB9G;AAED;;GAEG;AACH,wBAAgB,sBAAsB,IAAI,IAAI,CA8B7C;AAED;;GAEG;AACH,wBAAgB,gCAAgC,IAAI,IAAI,CAuDvD;AAED;;GAEG;AACH,wBAAgB,yBAAyB,IAAI,IAAI,CA6BhD;AAED,OAAO,EAAE,8BAA8B,EAAE,gBAAgB,EAAE,MAAM,OAAO,CAAC;AAwDzE,UAAU,4BAA4B;IACpC;;;OAGG;IACH,uBAAuB,EAAE,OAAO,CAAC;CAClC;AAED,qDAAqD;AACrD,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,IAAI,EAAE,OAAO,EAAE,4BAA4B,GAAG,IAAI,CA6G7F;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,CAC9B,IAAI,EAAE,IAAI,EACV,KAAK,EAAE,gBAAgB,EACvB,SAAS,EAAE,MAAM,EACjB,QAAQ,EAAE,MAAM,EAChB,UAAU,EAAE,MAAM,GACjB,MAAM,CAgCR;AA+FD;;;GAGG;AACH,wBAAgB,iBAAiB,CAC/B,IAAI,EAAE,IAAI,EACV,KAAK,EAAE,yBAAyB,EAChC,WAAW,EAAE,MAAM,EACnB,SAAS,EAAE,MAAM,EACjB,QAAQ,EAAE,MAAM,EAChB,UAAU,EAAE,MAAM,GACjB,IAAI,CAmDN"} | ||
| {"version":3,"file":"browserMetrics.d.ts","sourceRoot":"","sources":["../../../src/metrics/browserMetrics.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAgB,IAAI,EAAoC,MAAM,cAAc,CAAC;AA8EzF,UAAU,6BAA6B;IACrC,wBAAwB,EAAE,OAAO,CAAC;CACnC;AAED;;;;;GAKG;AACH,wBAAgB,sBAAsB,CAAC,EAAE,wBAAwB,EAAE,EAAE,6BAA6B,GAAG,MAAM,IAAI,CAqB9G;AAED;;GAEG;AACH,wBAAgB,sBAAsB,IAAI,IAAI,CA8B7C;AAED;;GAEG;AACH,wBAAgB,gCAAgC,IAAI,IAAI,CAuDvD;AAED;;GAEG;AACH,wBAAgB,yBAAyB,IAAI,IAAI,CA6BhD;AAED,OAAO,EAAE,8BAA8B,EAAE,gBAAgB,EAAE,MAAM,OAAO,CAAC;AAwDzE,UAAU,4BAA4B;IACpC;;;OAGG;IACH,uBAAuB,EAAE,OAAO,CAAC;CAClC;AAED,qDAAqD;AACrD,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,IAAI,EAAE,OAAO,EAAE,4BAA4B,GAAG,IAAI,CA6G7F;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,CAC9B,IAAI,EAAE,IAAI,EACV,KAAK,EAAE,gBAAgB,EACvB,SAAS,EAAE,MAAM,EACjB,QAAQ,EAAE,MAAM,EAChB,UAAU,EAAE,MAAM,GACjB,IAAI,CAiCN;AA+FD;;;GAGG;AACH,wBAAgB,iBAAiB,CAC/B,IAAI,EAAE,IAAI,EACV,KAAK,EAAE,yBAAyB,EAChC,WAAW,EAAE,MAAM,EACnB,SAAS,EAAE,MAAM,EACjB,QAAQ,EAAE,MAAM,EAChB,UAAU,EAAE,MAAM,GACjB,IAAI,CAmDN"} |
+2
-2
| { | ||
| "name": "@sentry-internal/browser-utils", | ||
| "version": "8.55.0", | ||
| "version": "8.55.1", | ||
| "description": "Browser Utilities for all Sentry JavaScript SDKs", | ||
@@ -42,3 +42,3 @@ "repository": "git://github.com/getsentry/sentry-javascript.git", | ||
| "dependencies": { | ||
| "@sentry/core": "8.55.0" | ||
| "@sentry/core": "8.55.1" | ||
| }, | ||
@@ -45,0 +45,0 @@ "scripts": { |
Network access
Supply chain riskThis module accesses the network.
Found 1 instance in 1 package
Long strings
Supply chain riskContains long string literals, which may be a sign of obfuscated or packed code.
Found 1 instance in 1 package
URL strings
Supply chain riskPackage contains fragments of external URLs or IP addresses, which the package may be accessing at runtime.
Found 1 instance in 1 package
Network access
Supply chain riskThis module accesses the network.
Found 1 instance in 1 package
Long strings
Supply chain riskContains long string literals, which may be a sign of obfuscated or packed code.
Found 1 instance in 1 package
URL strings
Supply chain riskPackage contains fragments of external URLs or IP addresses, which the package may be accessing at runtime.
Found 1 instance in 1 package
728390
0.09%7848
0.05%+ Added
- Removed
Updated