UNPKG

@zendesk/react-measure-timing-hooks

Version:

react hooks for measuring time to interactive and time to render of components

265 lines (239 loc) 8.59 kB
import './testUtility/asciiTimelineSerializer' import { describe, expect, it } from 'vitest' import { createCPUIdleProcessor } from './firstCPUIdle' import { Check, FMP, Idle, LongTask, makeEntries, } from './testUtility/makeTimeline' function getFirstCPUIdleEntry({ fmpTime, entries, }: { fmpTime: number | null entries: PerformanceEntry[] }) { const processor = createCPUIdleProcessor(fmpTime ?? 0) let firstCPUIdle for (const entry of entries) { const result = processor.processPerformanceEntry(entry) if (result !== undefined) { firstCPUIdle = result } } return firstCPUIdle } describe('createCPUIdleProcessor', () => { it('No long tasks after FMP, FirstCPUIdle immediately after FMP + quiet window', () => { const { entries, fmpTime } = makeEntries([ Idle(200), FMP, Idle(4_000), LongTask(400), ]) expect(entries).toMatchInlineSnapshot(` events | fmp task(400) timeline | |-<⋯ +4000 ⋯>-[++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++] time (ms) | 200 4200 `) const firstCPUIdle = getFirstCPUIdleEntry({ fmpTime, entries }) expect(firstCPUIdle).toEqual({ firstCpuIdle: 200 }) }) it('One light cluster after FMP, FirstCPUIdle at FMP', () => { const { entries, fmpTime } = makeEntries([ Idle(200), FMP, Idle(100), LongTask(50), Idle(50), LongTask(50), LongTask(50), Idle(2_550), Check, ]) expect(entries).toMatchInlineSnapshot(` events | fmp task(50) task(50) task(50) check timeline | |-------------------[++++++++]----------[++++++++]-[++++++++]-<⋯ +2550 ⋯>-| time (ms) | 200 300 400 450 3050 `) const firstCPUIdle = getFirstCPUIdleEntry({ fmpTime, entries }) expect(firstCPUIdle).toEqual({ firstCpuIdle: 200 }) }) it('One heavy cluster after FMP, FirstCPUIdle after the cluster', () => { const { entries, fmpTime } = makeEntries([ Idle(200), FMP, Idle(100), LongTask(50), Idle(50), LongTask(200), Idle(50), LongTask(50), Idle(2_500), Check, ]) expect(entries).toMatchInlineSnapshot(` events | fmp task(50) task(200) task(50) check timeline | |-----------[++++]------[+++++++++++++++++++++++]------[++++]-<⋯ +2500 ⋯>--| time (ms) | 200 300 400 650 3200 `) const firstCPUIdle = getFirstCPUIdleEntry({ fmpTime, entries }) expect(firstCPUIdle).toEqual({ firstCpuIdle: 700 }) }) it('Multiple heavy clusters, FirstCPUIdle updated to end of last cluster', () => { const { entries, fmpTime } = makeEntries([ Idle(200), FMP, Idle(100), LongTask(200), Idle(400), LongTask(200), Idle(400), LongTask(200), Idle(2_100), Check, ]) expect(entries).toMatchInlineSnapshot(` events | fmp task(200) task(200) task(200) check timeline | |---[+++++++]------------------[+++++++]------------------[+++++++]-<⋯ +2100 ⋯>--| time (ms) | 200 300 900 1500 3800 `) const firstCPUIdle = getFirstCPUIdleEntry({ fmpTime, entries }) const lastLongTask = entries.at(-2)! const expectedResult = lastLongTask.startTime + lastLongTask.duration expect(firstCPUIdle).toEqual({ firstCpuIdle: expectedResult }) }) it('Checking before the quiet window has passed - no long tasks processed, FirstCPUIdle not found', () => { const { entries, fmpTime } = makeEntries([Idle(200), FMP, Idle(200), Check]) expect(entries).toMatchInlineSnapshot(` events | fmp check timeline | |-<⋯ +200 ⋯>-| time (ms) | 200 400 `) const firstCPUIdle = getFirstCPUIdleEntry({ fmpTime, entries }) expect(firstCPUIdle).toEqual({ nextCheck: 2_400 }) }) it('One heavy cluster, followed by two light, value is after 1st heavy cluster', () => { const { entries, fmpTime } = makeEntries([ Idle(200), FMP, Idle(100), LongTask(200), Idle(100), LongTask(100), Idle(1_000), LongTask(200), Idle(1_000), LongTask(200), Idle(1_550), Check, ]) expect(entries).toMatchInlineSnapshot(` events | fmp task(200) task(100) task(200) task(200) check timeline | |----[+++++++++]-----[+++]-<⋯ +1000 ⋯>--[+++++++++]-<⋯ +1000 ⋯>-[+++++++++]-<⋯ +1550 ⋯>-| time (ms) | 200 300 600 1700 2900 4650 `) const firstCPUIdle = getFirstCPUIdleEntry({ fmpTime, entries }) const lastHeavyClusterLongTask = entries.at(2)! const expectedResult = lastHeavyClusterLongTask.startTime + lastHeavyClusterLongTask.duration expect(firstCPUIdle).toEqual({ firstCpuIdle: expectedResult }) }) it('Continuous heavy clusters', () => { const { entries, fmpTime } = makeEntries([ FMP, Idle(200), LongTask(300), Idle(50), LongTask(300), Idle(50), LongTask(300), Idle(50), LongTask(300), Idle(50), LongTask(300), Idle(50), LongTask(300), Idle(50), LongTask(300), Idle(50), LongTask(300), Idle(50), LongTask(300), Idle(50), LongTask(300), Idle(50), LongTask(300), Idle(50), LongTask(300), Idle(50), LongTask(300), Idle(50), LongTask(300), Idle(50), LongTask(300), Idle(50), Check, ]) expect(entries).toMatchInlineSnapshot(` events | task(300) task(300) task(300) task(300) task(300) task(300) task(300) task(300) events | fmp task(300) task(300) task(300) task(300) task(300) task(300) task(300) check timeline | |-[++]-[++]-[++]-[++]-[++]-[++]-[++]-[++]-[++]-[++]-[++]-[++]-[++]-[++]-[++]-|- time (ms) | 0 200 550 900 1250 1600 1950 2300 2650 3000 3350 3700 4050 4400 4750 5100 5450 `) const firstCPUIdle = getFirstCPUIdleEntry({ fmpTime, entries }) expect(firstCPUIdle).toEqual({ nextCheck: 7_450 }) }) it('Light cluster followed by a heavy cluster a second later, FirstCPUIdle updated', () => { const { entries, fmpTime } = makeEntries([ Idle(200), FMP, LongTask(50), Idle(50), LongTask(50), LongTask(50), Idle(1_050), LongTask(50), Idle(50), LongTask(50), Idle(50), LongTask(200), Idle(50), LongTask(200), Idle(2_050), Check, ]) expect(entries).toMatchInlineSnapshot(` events | task(50) task(50) task(50) events | fmp task(50) task(50) task(200) task(200) check timeline | [+]--[+]--[+]-<⋯ +1050 ⋯>[+]--[+]---[+++++++++++]---[+++++++++++]-<⋯ +2050 ⋯>--| time (ms) | 200 300 350 1450 1550 1650 1900 4150 `) const firstCPUIdle = getFirstCPUIdleEntry({ fmpTime, entries }) const lastLongTask = entries.at(-2)! const expectedResult = lastLongTask.startTime + lastLongTask.duration expect(firstCPUIdle).toEqual({ firstCpuIdle: expectedResult }) }) it('A long task overlaps FMP, we consider FirstCPUIdle after the long task', () => { const { entries, fmpTime } = makeEntries([ Idle(200), FMP, LongTask(110, { start: 150 }), // Overlaps with FMP Idle(2_300), Check, ]) expect(entries).toMatchInlineSnapshot(` events | events | task(110) fmp check timeline | [+++++++++++++++++++++++++++++++++++++++++++++++++++++]-<⋯ +2240 ⋯>-| timeline | -------------------------|-<⋯ +2300 ⋯>------------------------------- time (ms) | 150 200 2500 `) const firstCPUIdle = getFirstCPUIdleEntry({ fmpTime, entries }) const lastLongTask = entries.at(-2)! const expectedResult = lastLongTask.startTime + lastLongTask.duration expect(firstCPUIdle).toEqual({ firstCpuIdle: expectedResult }) }) })