-
Notifications
You must be signed in to change notification settings - Fork 140
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Browse files
Browse the repository at this point in the history
* β β»οΈ move `mockDocumentReadyState` in a common module And add the possibility to mock onload * β clone emitted view events Sometimes when checking for View events emitted in the past, the properties don't reflect the state at the time because they have been mutated in place. * β β»οΈ factorize the way we mock `window.performance.getEntries*` * β»οΈ make runOnReadyState stoppable * β»οΈ extract the code to polyfill "navigation" performance entry We'll use this in `trackNavigationTimings` next. * π [RUM-5785] fix track navigation timings on Safari In most browsers, when observing `PerformanceNavigationTiming` via a `PerformanceObserver` before the page is fully loaded, the same "navigation" entry is notified twice: * once with the "buffered" entry, even if it is incomplete * once when all the timings are defined, after the `load` event is complete. On Safari, the entry is only notified once. The SDK is only aware of the incomplete entry (which is discarded), so all timings related to the navigation entry are missing. To work around this issue and keep things simple, this commit removes the `PerformanceObserver` usage. Instead, we wait for the `load` event to be complete, and then just pick up the buffered navigation entry. This is similar to the strategy we use to generate the "document" resource, which works reliably. * β adjust related integration tests * π review feedbacks * β»οΈ NavigationTiming inherits from ResourceTiming The native PerformanceNavigationTiming is inheriting from PerformanceResourceTiming, so let's do the same for our interfaces, so we don't need to copy/paste/document the same properties. * β fix unit test in IE11
- Loading branch information
1 parent
482a025
commit 6e60bba
Showing
18 changed files
with
325 additions
and
230 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,15 +1,16 @@ | ||
import type { Configuration } from '../domain/configuration' | ||
import { noop } from '../tools/utils/functionUtils' | ||
import { DOM_EVENT, addEventListener } from './addEventListener' | ||
|
||
export function runOnReadyState( | ||
configuration: Configuration, | ||
expectedReadyState: 'complete' | 'interactive', | ||
callback: () => void | ||
) { | ||
): { stop: () => void } { | ||
if (document.readyState === expectedReadyState || document.readyState === 'complete') { | ||
callback() | ||
} else { | ||
const eventName = expectedReadyState === 'complete' ? DOM_EVENT.LOAD : DOM_EVENT.DOM_CONTENT_LOADED | ||
addEventListener(configuration, window, eventName, callback, { once: true }) | ||
return { stop: noop } | ||
} | ||
const eventName = expectedReadyState === 'complete' ? DOM_EVENT.LOAD : DOM_EVENT.DOM_CONTENT_LOADED | ||
return addEventListener(configuration, window, eventName, callback, { once: true }) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
import { isIE, type RelativeTime } from '@datadog/browser-core' | ||
import type { RumPerformanceNavigationTiming } from './performanceObservable' | ||
import { RumPerformanceEntryType } from './performanceObservable' | ||
import { getNavigationEntry } from './performanceUtils' | ||
|
||
describe('getNavigationEntry', () => { | ||
it('returns the navigation entry', () => { | ||
// Declare the expected value here, so TypeScript can make sure all expected fields are covered, | ||
// even though the actual value contains more fields. | ||
const expectation: jasmine.Expected<RumPerformanceNavigationTiming> = { | ||
entryType: RumPerformanceEntryType.NAVIGATION, | ||
initiatorType: 'navigation', | ||
name: jasmine.any(String), | ||
|
||
domComplete: jasmine.any(Number), | ||
domContentLoadedEventEnd: jasmine.any(Number), | ||
domInteractive: jasmine.any(Number), | ||
loadEventEnd: jasmine.any(Number), | ||
|
||
startTime: 0 as RelativeTime, | ||
duration: jasmine.any(Number), | ||
|
||
fetchStart: jasmine.any(Number), | ||
domainLookupStart: jasmine.any(Number), | ||
domainLookupEnd: jasmine.any(Number), | ||
connectStart: jasmine.any(Number), | ||
...(isIE() | ||
? ({} as unknown as { secureConnectionStart: RelativeTime }) | ||
: { secureConnectionStart: jasmine.any(Number) }), | ||
connectEnd: jasmine.any(Number), | ||
requestStart: jasmine.any(Number), | ||
responseStart: jasmine.any(Number), | ||
responseEnd: jasmine.any(Number), | ||
redirectStart: jasmine.any(Number), | ||
redirectEnd: jasmine.any(Number), | ||
decodedBodySize: jasmine.any(Number), | ||
encodedBodySize: jasmine.any(Number), | ||
transferSize: jasmine.any(Number), | ||
|
||
toJSON: jasmine.any(Function), | ||
} | ||
|
||
expect(getNavigationEntry()).toEqual(jasmine.objectContaining(expectation)) | ||
}) | ||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,20 +1,53 @@ | ||
import type { RelativeTime, TimeStamp } from '@datadog/browser-core' | ||
import { getRelativeTime, isNumber } from '@datadog/browser-core' | ||
import { assign, getRelativeTime, isNumber } from '@datadog/browser-core' | ||
import { | ||
RumPerformanceEntryType, | ||
supportPerformanceTimingEvent, | ||
type RumPerformanceNavigationTiming, | ||
} from './performanceObservable' | ||
|
||
export type RelativePerformanceTiming = { | ||
export function getNavigationEntry(): RumPerformanceNavigationTiming { | ||
if (supportPerformanceTimingEvent(RumPerformanceEntryType.NAVIGATION)) { | ||
const navigationEntry = performance.getEntriesByType( | ||
RumPerformanceEntryType.NAVIGATION | ||
)[0] as unknown as RumPerformanceNavigationTiming | ||
if (navigationEntry) { | ||
return navigationEntry | ||
} | ||
} | ||
|
||
const timings = computeTimingsFromDeprecatedPerformanceTiming() | ||
const entry = assign( | ||
{ | ||
entryType: RumPerformanceEntryType.NAVIGATION as const, | ||
initiatorType: 'navigation' as const, | ||
name: window.location.href, | ||
startTime: 0 as RelativeTime, | ||
duration: timings.responseEnd, | ||
decodedBodySize: 0, | ||
encodedBodySize: 0, | ||
transferSize: 0, | ||
toJSON: () => assign({}, entry, { toJSON: undefined }), | ||
}, | ||
timings | ||
) | ||
return entry | ||
} | ||
|
||
export type TimingsFromDeprecatedPerformanceTiming = { | ||
-readonly [key in keyof Omit<PerformanceTiming, 'toJSON'>]: RelativeTime | ||
} | ||
|
||
export function computeRelativePerformanceTiming() { | ||
const result: Partial<RelativePerformanceTiming> = {} | ||
export function computeTimingsFromDeprecatedPerformanceTiming() { | ||
const result: Partial<TimingsFromDeprecatedPerformanceTiming> = {} | ||
const timing = performance.timing | ||
|
||
for (const key in timing) { | ||
if (isNumber(timing[key as keyof PerformanceTiming])) { | ||
const numberKey = key as keyof RelativePerformanceTiming | ||
const numberKey = key as keyof TimingsFromDeprecatedPerformanceTiming | ||
const timingElement = timing[numberKey] as TimeStamp | ||
result[numberKey] = timingElement === 0 ? (0 as RelativeTime) : getRelativeTime(timingElement) | ||
} | ||
} | ||
return result as RelativePerformanceTiming | ||
return result as TimingsFromDeprecatedPerformanceTiming | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.