Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

✨[RUMF-473] collect view loading time in ns and integrate the load event timing in the loading time calculation #401

Merged
merged 11 commits into from
May 26, 2020
6 changes: 3 additions & 3 deletions packages/rum/src/trackPageActivities.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import { monitor, Observable } from '@datadog/browser-core'
import { LifeCycle, LifeCycleEventType, Subscription } from './lifeCycle'

// Delay to wait for a page activity to validate the tracking process
// Delay to wait for a page activity to validate the tracking process in ms
export const PAGE_ACTIVITY_VALIDATION_DELAY = 100
// Delay to wait after a page activity to end the tracking process
// Delay to wait after a page activity to end the tracking process in ms
export const PAGE_ACTIVITY_END_DELAY = 100
// Maximum duration of the tracking process
// Maximum duration of the tracking process in ms
mquentin marked this conversation as resolved.
Show resolved Hide resolved
export const PAGE_ACTIVITY_MAX_DURATION = 10_000

export interface PageActivityEvent {
Expand Down
4 changes: 2 additions & 2 deletions packages/rum/src/userActionCollection.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Context, DOM_EVENT, generateUUID, noop } from '@datadog/browser-core'
import { Context, DOM_EVENT, generateUUID, msToNs } from '@datadog/browser-core'
mquentin marked this conversation as resolved.
Show resolved Hide resolved
import { getElementContent } from './getElementContent'
import { LifeCycle, LifeCycleEventType } from './lifeCycle'
import { trackEventCounts } from './trackEventCounts'
Expand Down Expand Up @@ -83,7 +83,7 @@ function newUserAction(lifeCycle: LifeCycle, type: UserActionType, name: string)
name,
startTime,
type,
duration: endTime - startTime,
duration: msToNs(endTime - startTime),
mquentin marked this conversation as resolved.
Show resolved Hide resolved
measures: {
errorCount: eventCounts.errorCount,
longTaskCount: eventCounts.longTaskCount,
Expand Down
8 changes: 6 additions & 2 deletions packages/rum/src/viewCollection.ts
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,10 @@ function newView(
updateView()

function updateView() {
if (measures.loadEventEnd) {
loadingTime = Math.max(measures.loadEventEnd, loadingTime || 0)
}

documentVersion += 1
lifeCycle.notify(LifeCycleEventType.VIEW_COLLECTED, {
documentVersion,
Expand Down Expand Up @@ -196,10 +200,10 @@ function trackTimings(lifeCycle: LifeCycle, callback: (timings: Timings) => void
}

function trackLoadingTime(lifeCycle: LifeCycle, callback: (loadingTimeValue: number | undefined) => void) {
const startTime: number = performance.now()
const startTime = performance.now()
const { stop: stopWaitIdlePageActivity } = waitIdlePageActivity(lifeCycle, (hadActivity, endTime) => {
if (hadActivity) {
callback(endTime - startTime)
callback(msToNs(endTime - startTime))
} else {
callback(undefined)
}
Expand Down
4 changes: 2 additions & 2 deletions packages/rum/test/userActionCollection.spec.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { DOM_EVENT, ErrorMessage } from '@datadog/browser-core'
import { DOM_EVENT, ErrorMessage, msToNs } from '@datadog/browser-core'
mquentin marked this conversation as resolved.
Show resolved Hide resolved
import { LifeCycle, LifeCycleEventType } from '../src/lifeCycle'
import { PAGE_ACTIVITY_MAX_DURATION, PAGE_ACTIVITY_VALIDATION_DELAY } from '../src/trackPageActivities'
import {
Expand Down Expand Up @@ -111,7 +111,7 @@ describe('startUserActionCollection', () => {
mockValidatedClickUserAction()
expect(events).toEqual([
{
duration: BEFORE_PAGE_ACTIVITY_VALIDATION_DELAY,
duration: msToNs(BEFORE_PAGE_ACTIVITY_VALIDATION_DELAY),
id: jasmine.any(String),
measures: {
errorCount: 0,
Expand Down
63 changes: 61 additions & 2 deletions packages/rum/test/viewCollection.spec.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { getHash, getPathName, getSearch } from '@datadog/browser-core'
import { getHash, getPathName, getSearch, msToNs } from '@datadog/browser-core'

import { LifeCycle, LifeCycleEventType } from '../src/lifeCycle'
import { PerformanceLongTaskTiming, PerformancePaintTiming } from '../src/rum'
Expand Down Expand Up @@ -170,7 +170,7 @@ describe('rum track loading time', () => {
jasmine.clock().tick(AFTER_PAGE_ACTIVITY_END_DELAY)
jasmine.clock().tick(THROTTLE_VIEW_UPDATE_PERIOD)

expect(getViewEvent(1).loadingTime).toEqual(BEFORE_PAGE_ACTIVITY_VALIDATION_DELAY)
expect(getViewEvent(1).loadingTime).toEqual(msToNs(BEFORE_PAGE_ACTIVITY_VALIDATION_DELAY))
})
})

Expand Down Expand Up @@ -308,6 +308,65 @@ describe('rum view measures', () => {
jasmine.clock().uninstall()
})

it('should have a loadEventEnd loading time when having no activity', () => {
mquentin marked this conversation as resolved.
Show resolved Hide resolved
jasmine.clock().install()
expect(getRumEventCount()).toEqual(1)
expect(getViewEvent(0).measures).toEqual({
errorCount: 0,
longTaskCount: 0,
resourceCount: 0,
userActionCount: 0,
})
mquentin marked this conversation as resolved.
Show resolved Hide resolved

lifeCycle.notify(
LifeCycleEventType.PERFORMANCE_ENTRY_COLLECTED,
FAKE_NAVIGATION_ENTRY as PerformanceNavigationTiming
)

expect(getRumEventCount()).toEqual(1)
bcaudan marked this conversation as resolved.
Show resolved Hide resolved

jasmine.clock().tick(THROTTLE_VIEW_UPDATE_PERIOD)

expect(getRumEventCount()).toEqual(2)
expect(getViewEvent(1).measures.loadEventEnd).toEqual(567e6)
expect(getViewEvent(1).loadingTime).toEqual(getViewEvent(1).measures.loadEventEnd)

jasmine.clock().uninstall()
})

it('should have a loadEventEnd loading time when load event happens after all activity completions', () => {
mquentin marked this conversation as resolved.
Show resolved Hide resolved
jasmine.clock().install()
expect(getRumEventCount()).toEqual(1)
expect(getViewEvent(0).measures).toEqual({
errorCount: 0,
longTaskCount: 0,
resourceCount: 0,
userActionCount: 0,
})

expect(getRumEventCount()).toEqual(1)

jasmine.clock().tick(BEFORE_PAGE_ACTIVITY_VALIDATION_DELAY)
lifeCycle.notify(LifeCycleEventType.DOM_MUTATED)
jasmine.clock().tick(AFTER_PAGE_ACTIVITY_END_DELAY)
jasmine.clock().tick(THROTTLE_VIEW_UPDATE_PERIOD)

expect(getRumEventCount()).toEqual(2)
expect(getViewEvent(1).loadingTime).toBeLessThan(567e6)
mquentin marked this conversation as resolved.
Show resolved Hide resolved
mquentin marked this conversation as resolved.
Show resolved Hide resolved

lifeCycle.notify(
LifeCycleEventType.PERFORMANCE_ENTRY_COLLECTED,
FAKE_NAVIGATION_ENTRY as PerformanceNavigationTiming
)
jasmine.clock().tick(THROTTLE_VIEW_UPDATE_PERIOD)

expect(getRumEventCount()).toEqual(3)
expect(getViewEvent(2).measures.loadEventEnd).toEqual(567e6)
expect(getViewEvent(2).loadingTime).toEqual(getViewEvent(2).measures.loadEventEnd)

jasmine.clock().uninstall()
})
mquentin marked this conversation as resolved.
Show resolved Hide resolved

it('should update measures when notified with a RESOURCE_ADDED_TO_BATCH event (throttled)', () => {
jasmine.clock().install()
expect(getRumEventCount()).toEqual(1)
Expand Down