Skip to content

Commit eafc575

Browse files
committed
selector performance measurement experiment
1 parent 28f0aa2 commit eafc575

File tree

1 file changed

+34
-1
lines changed

1 file changed

+34
-1
lines changed

src/hooks/useSelector.ts

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { useCallback, useDebugValue, useRef } from 'react'
1+
import { useCallback, useDebugValue, useId, useRef, useState } from 'react'
22

33
import {
44
createReduxContextHook,
@@ -11,6 +11,18 @@ import { notInitialized } from '../utils/useSyncExternalStore'
1111

1212
export type CheckFrequency = 'never' | 'once' | 'always'
1313

14+
interface Measure {
15+
duration: number
16+
startTime: number
17+
detail: { loc: string; trace: string; uid: string; code: string }
18+
}
19+
type Loc = string
20+
type Uid = string
21+
const measurements: Record<Loc, Record<Uid, Measure[]>> = {}
22+
// @ts-ignore
23+
// eslint-disable-next-line no-undef
24+
globalThis[Symbol.for('react-redux-selector-measurements')] = measurements
25+
1426
export interface UseSelectorOptions<Selected = unknown> {
1527
equalityFn?: EqualityFn<Selected>
1628
stabilityCheck?: CheckFrequency
@@ -84,10 +96,31 @@ export function createSelectorHook(context = ReactReduxContext): UseSelector {
8496

8597
const firstRun = useRef(true)
8698

99+
const [trace] = useState<string>(() => {
100+
try {
101+
throw new Error()
102+
} catch (e) {
103+
return e.stack
104+
}
105+
})
106+
const arr = trace.split('\n')
107+
const loc = arr[arr.findIndex((x) => x.startsWith('useSelector')) + 1]
108+
const uid = useId()
109+
87110
const wrappedSelector = useCallback<typeof selector>(
88111
{
89112
[selector.name](state: TState) {
113+
performance.mark('selectorStart')
90114
const selected = selector(state)
115+
performance.mark('selectorEnd')
116+
// @ts-ignore
117+
const measure = performance.measure('selector', {
118+
start: 'selectorStart',
119+
end: 'selectorEnd',
120+
detail: { trace, loc, uid, code: selector.toString() },
121+
}) as any as Measure
122+
;((measurements[loc] ??= {})[uid] ??= []).push(measure)
123+
91124
if (process.env.NODE_ENV !== 'production') {
92125
const finalStabilityCheck =
93126
typeof stabilityCheck === 'undefined'

0 commit comments

Comments
 (0)