@@ -342,15 +342,34 @@ export function _addMeasureSpans(
342
342
duration : number ,
343
343
timeOrigin : number ,
344
344
) : number {
345
- const measureStartTimestamp = timeOrigin + startTime ;
346
- const measureEndTimestamp = measureStartTimestamp + duration ;
345
+ const navEntry = getNavigationEntry ( ) ;
346
+ const requestTime = msToSec ( navEntry ? navEntry . requestStart : 0 ) ;
347
+ // Because performance.measure accepts arbitrary timestamps it can produce
348
+ // spans that happen before the browser even makes a request for the page.
349
+ //
350
+ // An example of this is the automatically generated Next.js-before-hydration
351
+ // spans created by the Next.js framework.
352
+ //
353
+ // To prevent this we will pin the start timestamp to the request start time
354
+ // This does make duration inaccruate, so if this does happen, we will add
355
+ // an attribute to the span
356
+ const measureStartTimestamp = timeOrigin + Math . max ( startTime , requestTime ) ;
357
+ const startTimeStamp = timeOrigin + startTime ;
358
+ const measureEndTimestamp = startTimeStamp + duration ;
359
+
360
+ const attributes : SpanAttributes = {
361
+ [ SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN ] : 'auto.resource.browser.metrics' ,
362
+ } ;
363
+
364
+ if ( measureStartTimestamp !== startTimeStamp ) {
365
+ attributes [ 'sentry.browser.measure_happened_before_request' ] = true ;
366
+ attributes [ 'sentry.browser.measure_start_time' ] = measureStartTimestamp ;
367
+ }
347
368
348
369
startAndEndSpan ( span , measureStartTimestamp , measureEndTimestamp , {
349
370
name : entry . name as string ,
350
371
op : entry . entryType as string ,
351
- attributes : {
352
- [ SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN ] : 'auto.resource.browser.metrics' ,
353
- } ,
372
+ attributes,
354
373
} ) ;
355
374
356
375
return measureStartTimestamp ;
@@ -395,36 +414,29 @@ function _addPerformanceNavigationTiming(
395
414
/** Create request and response related spans */
396
415
// eslint-disable-next-line @typescript-eslint/no-explicit-any
397
416
function _addRequest ( span : Span , entry : Record < string , any > , timeOrigin : number ) : void {
417
+ const requestStartTimestamp = timeOrigin + msToSec ( entry . requestStart as number ) ;
418
+ const responseEndTimestamp = timeOrigin + msToSec ( entry . responseEnd as number ) ;
419
+ const responseStartTimestamp = timeOrigin + msToSec ( entry . responseStart as number ) ;
398
420
if ( entry . responseEnd ) {
399
421
// 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.
400
422
// In this case, ie. when the document request hasn't finished yet, `entry.responseEnd` will be 0.
401
423
// In order not to produce faulty spans, where the end timestamp is before the start timestamp, we will only collect
402
424
// these spans when the responseEnd value is available. The backend (Relay) would drop the entire span if it contained faulty spans.
403
- startAndEndSpan (
404
- span ,
405
- timeOrigin + msToSec ( entry . requestStart as number ) ,
406
- timeOrigin + msToSec ( entry . responseEnd as number ) ,
407
- {
408
- op : 'browser' ,
409
- name : 'request' ,
410
- attributes : {
411
- [ SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN ] : 'auto.ui.browser.metrics' ,
412
- } ,
425
+ startAndEndSpan ( span , requestStartTimestamp , responseEndTimestamp , {
426
+ op : 'browser' ,
427
+ name : 'request' ,
428
+ attributes : {
429
+ [ SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN ] : 'auto.ui.browser.metrics' ,
413
430
} ,
414
- ) ;
431
+ } ) ;
415
432
416
- startAndEndSpan (
417
- span ,
418
- timeOrigin + msToSec ( entry . responseStart as number ) ,
419
- timeOrigin + msToSec ( entry . responseEnd as number ) ,
420
- {
421
- op : 'browser' ,
422
- name : 'response' ,
423
- attributes : {
424
- [ SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN ] : 'auto.ui.browser.metrics' ,
425
- } ,
433
+ startAndEndSpan ( span , responseStartTimestamp , responseEndTimestamp , {
434
+ op : 'browser' ,
435
+ name : 'response' ,
436
+ attributes : {
437
+ [ SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN ] : 'auto.ui.browser.metrics' ,
426
438
} ,
427
- ) ;
439
+ } ) ;
428
440
}
429
441
}
430
442
0 commit comments