Skip to content

Commit

Permalink
[RUM] review feedbacks
Browse files Browse the repository at this point in the history
* simplify and move getRelativePerformanceTiming into the `utils` module
* don't try to support older versions of safari and firefox
* use `handlePerformanceEntries` when emulating the "navigation" timing
event
* remove the unused "duration" property from the fake "navigation"
timing event
* rename startPerformanceCollection.ts to performanceCollection.ts
  • Loading branch information
BenoitZugmeyer committed Oct 21, 2019
1 parent 049a8f8 commit 15da132
Show file tree
Hide file tree
Showing 3 changed files with 31 additions and 30 deletions.
6 changes: 6 additions & 0 deletions packages/core/src/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -158,3 +158,9 @@ export function includes(candidate: unknown[], search: unknown) {
export function isPercentage(value: unknown) {
return typeof value === 'number' && value >= 0 && value <= 100
}

export function getRelativePerformanceTiming(performance: Performance, timestamp: number) {
// performance.timeOrigin is undefined in WebKit, see https://bugs.webkit.org/show_bug.cgi?id=174862
const timeOrigin = performance.timeOrigin !== undefined ? performance.timeOrigin : performance.timing.navigationStart
return timestamp - timeOrigin
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { monitor } from '@browser-agent/core/src/internalMonitoring'
import { Observable } from '@browser-agent/core/src/observable'
import { getRelativePerformanceTiming } from '@browser-agent/core/src/utils'
import { RumSession } from './rumSession'

declare global {
Expand All @@ -13,20 +14,19 @@ function supportPerformanceObject() {
}

function supportPerformanceNavigationTimingEvent() {
if (PerformanceObserver.supportedEntryTypes) {
return PerformanceObserver.supportedEntryTypes.includes('navigation')
}

return supportPerformanceObject() && performance.getEntriesByType('navigation').length > 0
return (
PerformanceObserver.supportedEntryTypes !== undefined &&
PerformanceObserver.supportedEntryTypes.includes('navigation')
)
}

export function startPerformanceCollection(performanceObservable: Observable<PerformanceEntry>, session: RumSession) {
if (supportPerformanceObject()) {
handlePerformanceEntries(session, performanceObservable, performance)
handlePerformanceEntries(session, performanceObservable, performance.getEntries())
}
if (window.PerformanceObserver) {
const observer = new PerformanceObserver(
monitor((entries) => handlePerformanceEntries(session, performanceObservable, entries))
monitor((entries) => handlePerformanceEntries(session, performanceObservable, entries.getEntries()))
)
observer.observe({ entryTypes: ['resource', 'navigation', 'paint', 'longtask'] })

Expand All @@ -37,7 +37,7 @@ export function startPerformanceCollection(performanceObservable: Observable<Per
})

if (!supportPerformanceNavigationTimingEvent()) {
emulatePerformanceNavigationTiming(performanceObservable, performance)
emulatePerformanceNavigationTiming(session, performanceObservable, performance)
}
}
}
Expand All @@ -52,16 +52,8 @@ const performanceNavigationTimingNames = [
'loadEventEnd' as 'loadEventEnd',
]

function getRelativePerformanceTiming<T extends Exclude<keyof PerformanceTiming, 'toJSON'>>(
performance: Performance,
name: T
) {
// performance.timeOrigin is undefined in WebKit, see https://bugs.webkit.org/show_bug.cgi?id=174862
const timeOrigin = performance.timeOrigin !== undefined ? performance.timeOrigin : performance.timing.navigationStart
return performance.timing[name] - timeOrigin
}

function emulatePerformanceNavigationTiming(
session: RumSession,
performanceObservable: Observable<PerformanceEntry>,
performance: Performance
) {
Expand All @@ -71,12 +63,10 @@ function emulatePerformanceNavigationTiming(
}

for (const timingName of performanceNavigationTimingNames) {
event[timingName] = getRelativePerformanceTiming(performance, timingName)
event[timingName] = getRelativePerformanceTiming(performance, performance.timing[timingName])
}

event.duration = event.loadEventEnd

performanceObservable.notify(event as PerformanceNavigationTiming)
handlePerformanceEntries(session, performanceObservable, [event as PerformanceNavigationTiming])
}

if (document.readyState === 'complete') {
Expand All @@ -95,17 +85,22 @@ function emulatePerformanceNavigationTiming(
function handlePerformanceEntries(
session: RumSession,
performanceObservable: Observable<PerformanceEntry>,
entries: Performance | PerformanceObserverEntryList
entries: PerformanceEntry[]
) {
function notify(entry: PerformanceEntry) {
performanceObservable.notify(entry)
}

if (session.isTrackedWithResource()) {
entries.getEntriesByType('resource').forEach((entry) => performanceObservable.notify(entry))
entries.filter((entry) => entry.entryType === 'resource').forEach(notify)
}

entries
.getEntriesByType('navigation')
.forEach((entry) => (entry as PerformanceNavigationTiming).loadEventEnd > 0 && performanceObservable.notify(entry))
entries.getEntriesByType('paint').forEach((entry) => performanceObservable.notify(entry))
.filter((entry) => entry.entryType === 'navigation')
// Exclude incomplete navigation entries by filtering out those who have a loadEventEnd at 0
.filter((entry) => (entry as PerformanceNavigationTiming).loadEventEnd > 0)
.forEach(notify)

if (entries !== window.performance) {
entries.getEntriesByType('longtask').forEach((entry) => performanceObservable.notify(entry))
}
entries.filter((entry) => entry.entryType === 'paint').forEach(notify)
entries.filter((entry) => entry.entryType === 'longtask').forEach(notify)
}
2 changes: 1 addition & 1 deletion packages/rum/src/rum.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,10 @@ import { Batch, HttpRequest } from '@browser-agent/core/src/transport'
import { Context, ContextValue, includes, msToNs, ResourceKind, withSnakeCaseKeys } from '@browser-agent/core/src/utils'
import { matchRequestTiming } from './matchRequestTiming'
import { pageViewId, PageViewPerformance, PageViewSummary, trackPageView } from './pageViewTracker'
import { startPerformanceCollection } from './performanceCollection'
import { computePerformanceResourceDetails, computeResourceKind, computeSize, isValidResource } from './resourceUtils'
import { RumGlobal } from './rum.entry'
import { RumSession } from './rumSession'
import { startPerformanceCollection } from './startPerformanceCollection'

export interface PerformancePaintTiming extends PerformanceEntry {
entryType: 'paint'
Expand Down

0 comments on commit 15da132

Please sign in to comment.