Skip to content

Commit 1300365

Browse files
authored
Pass "start time" and "commit time" to Profiler callback (#12852)
* Added start time parameter to Profiler onRender callback * Profiler also captures commit time * Only init Profiler stateNode if enableProfilerTimer feature flag enabled
1 parent 12c8a88 commit 1300365

File tree

5 files changed

+229
-96
lines changed

5 files changed

+229
-96
lines changed

packages/react-reconciler/src/ReactFiber.js

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -460,10 +460,13 @@ export function createFiberFromProfiler(
460460
const fiber = createFiber(Profiler, pendingProps, key, mode | ProfileMode);
461461
fiber.type = REACT_PROFILER_TYPE;
462462
fiber.expirationTime = expirationTime;
463-
fiber.stateNode = {
464-
duration: 0,
465-
startTime: 0,
466-
};
463+
if (enableProfilerTimer) {
464+
fiber.stateNode = {
465+
elapsedPauseTimeAtStart: 0,
466+
duration: 0,
467+
startTime: 0,
468+
};
469+
}
467470

468471
return fiber;
469472
}

packages/react-reconciler/src/ReactFiberCommitWork.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ import type {ExpirationTime} from './ReactFiberExpirationTime';
2020
import type {CapturedValue, CapturedError} from './ReactCapturedValue';
2121

2222
import {enableProfilerTimer} from 'shared/ReactFeatureFlags';
23+
import {getCommitTime} from './ReactProfilerTimer';
2324
import {
2425
ClassComponent,
2526
HostRoot,
@@ -807,6 +808,8 @@ function commitWork(current: Fiber | null, finishedWork: Fiber): void {
807808
current === null ? 'mount' : 'update',
808809
finishedWork.stateNode.duration,
809810
finishedWork.treeBaseTime,
811+
finishedWork.stateNode.startTime,
812+
getCommitTime(),
810813
);
811814

812815
// Reset actualTime after successful commit.

packages/react-reconciler/src/ReactFiberScheduler.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,7 @@ import {popHostContext, popHostContainer} from './ReactFiberHostContext';
104104
import {
105105
checkActualRenderTimeStackEmpty,
106106
pauseActualRenderTimerIfRunning,
107+
recordCommitTime,
107108
recordElapsedBaseRenderTimeIfRunning,
108109
resetActualRenderTimer,
109110
resumeActualRenderTimerIfPaused,
@@ -566,6 +567,10 @@ function commitRoot(finishedWork: Fiber): ExpirationTime {
566567
}
567568
stopCommitSnapshotEffectsTimer();
568569

570+
if (enableProfilerTimer) {
571+
recordCommitTime();
572+
}
573+
569574
// Commit all the side-effects within a tree. We'll do this in two passes.
570575
// The first pass performs all the host insertions, updates, deletions and
571576
// ref unmounts.

packages/react-reconciler/src/ReactProfilerTimer.js

Lines changed: 32 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -14,25 +14,40 @@ import {enableProfilerTimer} from 'shared/ReactFeatureFlags';
1414
import warning from 'fbjs/lib/warning';
1515
import {now} from './ReactFiberHostConfig';
1616

17-
/**
18-
* The "actual" render time is total time required to render the descendants of a Profiler component.
19-
* This time is stored as a stack, since Profilers can be nested.
20-
* This time is started during the "begin" phase and stopped during the "complete" phase.
21-
* It is paused (and accumulated) in the event of an interruption or an aborted render.
22-
*/
23-
2417
export type ProfilerTimer = {
2518
checkActualRenderTimeStackEmpty(): void,
19+
getCommitTime(): number,
2620
markActualRenderTimeStarted(fiber: Fiber): void,
2721
pauseActualRenderTimerIfRunning(): void,
2822
recordElapsedActualRenderTime(fiber: Fiber): void,
2923
resetActualRenderTimer(): void,
3024
resumeActualRenderTimerIfPaused(): void,
25+
recordCommitTime(): void,
3126
recordElapsedBaseRenderTimeIfRunning(fiber: Fiber): void,
3227
startBaseRenderTimer(): void,
3328
stopBaseRenderTimerIfRunning(): void,
3429
};
3530

31+
let commitTime: number = 0;
32+
33+
function getCommitTime(): number {
34+
return commitTime;
35+
}
36+
37+
function recordCommitTime(): void {
38+
if (!enableProfilerTimer) {
39+
return;
40+
}
41+
commitTime = now();
42+
}
43+
44+
/**
45+
* The "actual" render time is total time required to render the descendants of a Profiler component.
46+
* This time is stored as a stack, since Profilers can be nested.
47+
* This time is started during the "begin" phase and stopped during the "complete" phase.
48+
* It is paused (and accumulated) in the event of an interruption or an aborted render.
49+
*/
50+
3651
let fiberStack: Array<Fiber | null>;
3752

3853
if (__DEV__) {
@@ -61,7 +76,9 @@ function markActualRenderTimeStarted(fiber: Fiber): void {
6176
if (__DEV__) {
6277
fiberStack.push(fiber);
6378
}
64-
fiber.stateNode.startTime = now() - totalElapsedPauseTime;
79+
const stateNode = fiber.stateNode;
80+
stateNode.elapsedPauseTimeAtStart = totalElapsedPauseTime;
81+
stateNode.startTime = now();
6582
}
6683

6784
function pauseActualRenderTimerIfRunning(): void {
@@ -80,8 +97,11 @@ function recordElapsedActualRenderTime(fiber: Fiber): void {
8097
if (__DEV__) {
8198
warning(fiber === fiberStack.pop(), 'Unexpected Fiber popped.');
8299
}
83-
fiber.stateNode.duration +=
84-
now() - totalElapsedPauseTime - fiber.stateNode.startTime;
100+
const stateNode = fiber.stateNode;
101+
stateNode.duration +=
102+
now() -
103+
(totalElapsedPauseTime - stateNode.elapsedPauseTimeAtStart) -
104+
stateNode.startTime;
85105
}
86106

87107
function resetActualRenderTimer(): void {
@@ -145,8 +165,10 @@ function stopBaseRenderTimerIfRunning(): void {
145165

146166
export {
147167
checkActualRenderTimeStackEmpty,
168+
getCommitTime,
148169
markActualRenderTimeStarted,
149170
pauseActualRenderTimerIfRunning,
171+
recordCommitTime,
150172
recordElapsedActualRenderTime,
151173
resetActualRenderTimer,
152174
resumeActualRenderTimerIfPaused,

0 commit comments

Comments
 (0)