Skip to content

Commit

Permalink
Store commit durations on HostRoot for DevTools access (#20983)
Browse files Browse the repository at this point in the history
Also add missing feature flag wrappers around effect duration attributes.
  • Loading branch information
Brian Vaughn authored Mar 16, 2021
1 parent 89acfa6 commit 466b26c
Show file tree
Hide file tree
Showing 8 changed files with 144 additions and 72 deletions.
25 changes: 15 additions & 10 deletions packages/react-reconciler/src/ReactFiberBeginWork.new.js
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ import {
debugRenderPhaseSideEffectsForStrictMode,
disableLegacyContext,
disableModulePatternComponents,
enableProfilerCommitHooks,
enableProfilerTimer,
enableSchedulerTracing,
enableSuspenseServerRenderer,
Expand Down Expand Up @@ -837,11 +838,13 @@ function updateProfiler(
if (enableProfilerTimer) {
workInProgress.flags |= Update;

// Reset effect durations for the next eventual effect phase.
// These are reset during render to allow the DevTools commit hook a chance to read them,
const stateNode = workInProgress.stateNode;
stateNode.effectDuration = 0;
stateNode.passiveEffectDuration = 0;
if (enableProfilerCommitHooks) {
// Reset effect durations for the next eventual effect phase.
// These are reset during render to allow the DevTools commit hook a chance to read them,
const stateNode = workInProgress.stateNode;
stateNode.effectDuration = 0;
stateNode.passiveEffectDuration = 0;
}
}
const nextProps = workInProgress.pendingProps;
const nextChildren = nextProps.children;
Expand Down Expand Up @@ -3320,11 +3323,13 @@ function beginWork(
workInProgress.flags |= Update;
}

// Reset effect durations for the next eventual effect phase.
// These are reset during render to allow the DevTools commit hook a chance to read them,
const stateNode = workInProgress.stateNode;
stateNode.effectDuration = 0;
stateNode.passiveEffectDuration = 0;
if (enableProfilerCommitHooks) {
// Reset effect durations for the next eventual effect phase.
// These are reset during render to allow the DevTools commit hook a chance to read them,
const stateNode = workInProgress.stateNode;
stateNode.effectDuration = 0;
stateNode.passiveEffectDuration = 0;
}
}
break;
case SuspenseComponent: {
Expand Down
25 changes: 15 additions & 10 deletions packages/react-reconciler/src/ReactFiberBeginWork.old.js
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ import {
debugRenderPhaseSideEffectsForStrictMode,
disableLegacyContext,
disableModulePatternComponents,
enableProfilerCommitHooks,
enableProfilerTimer,
enableSchedulerTracing,
enableSuspenseServerRenderer,
Expand Down Expand Up @@ -837,11 +838,13 @@ function updateProfiler(
if (enableProfilerTimer) {
workInProgress.flags |= Update;

// Reset effect durations for the next eventual effect phase.
// These are reset during render to allow the DevTools commit hook a chance to read them,
const stateNode = workInProgress.stateNode;
stateNode.effectDuration = 0;
stateNode.passiveEffectDuration = 0;
if (enableProfilerCommitHooks) {
// Reset effect durations for the next eventual effect phase.
// These are reset during render to allow the DevTools commit hook a chance to read them,
const stateNode = workInProgress.stateNode;
stateNode.effectDuration = 0;
stateNode.passiveEffectDuration = 0;
}
}
const nextProps = workInProgress.pendingProps;
const nextChildren = nextProps.children;
Expand Down Expand Up @@ -3320,11 +3323,13 @@ function beginWork(
workInProgress.flags |= Update;
}

// Reset effect durations for the next eventual effect phase.
// These are reset during render to allow the DevTools commit hook a chance to read them,
const stateNode = workInProgress.stateNode;
stateNode.effectDuration = 0;
stateNode.passiveEffectDuration = 0;
if (enableProfilerCommitHooks) {
// Reset effect durations for the next eventual effect phase.
// These are reset during render to allow the DevTools commit hook a chance to read them,
const stateNode = workInProgress.stateNode;
stateNode.effectDuration = 0;
stateNode.passiveEffectDuration = 0;
}
}
break;
case SuspenseComponent: {
Expand Down
30 changes: 20 additions & 10 deletions packages/react-reconciler/src/ReactFiberCommitWork.new.js
Original file line number Diff line number Diff line change
Expand Up @@ -578,11 +578,16 @@ export function commitPassiveEffectDurations(
// Bubble times to the next nearest ancestor Profiler.
// After we process that Profiler, we'll bubble further up.
let parentFiber = finishedWork.return;
while (parentFiber !== null) {
if (parentFiber.tag === Profiler) {
const parentStateNode = parentFiber.stateNode;
parentStateNode.passiveEffectDuration += passiveEffectDuration;
break;
outer: while (parentFiber !== null) {
switch (parentFiber.tag) {
case HostRoot:
const root = parentFiber.stateNode;
root.passiveEffectDuration += passiveEffectDuration;
break outer;
case Profiler:
const parentStateNode = parentFiber.stateNode;
parentStateNode.passiveEffectDuration += passiveEffectDuration;
break outer;
}
parentFiber = parentFiber.return;
}
Expand Down Expand Up @@ -885,11 +890,16 @@ function commitLayoutEffectOnFiber(
// Propagate layout effect durations to the next nearest Profiler ancestor.
// Do not reset these values until the next render so DevTools has a chance to read them first.
let parentFiber = finishedWork.return;
while (parentFiber !== null) {
if (parentFiber.tag === Profiler) {
const parentStateNode = parentFiber.stateNode;
parentStateNode.effectDuration += effectDuration;
break;
outer: while (parentFiber !== null) {
switch (parentFiber.tag) {
case HostRoot:
const root = parentFiber.stateNode;
root.effectDuration += effectDuration;
break outer;
case Profiler:
const parentStateNode = parentFiber.stateNode;
parentStateNode.effectDuration += effectDuration;
break outer;
}
parentFiber = parentFiber.return;
}
Expand Down
30 changes: 20 additions & 10 deletions packages/react-reconciler/src/ReactFiberCommitWork.old.js
Original file line number Diff line number Diff line change
Expand Up @@ -578,11 +578,16 @@ export function commitPassiveEffectDurations(
// Bubble times to the next nearest ancestor Profiler.
// After we process that Profiler, we'll bubble further up.
let parentFiber = finishedWork.return;
while (parentFiber !== null) {
if (parentFiber.tag === Profiler) {
const parentStateNode = parentFiber.stateNode;
parentStateNode.passiveEffectDuration += passiveEffectDuration;
break;
outer: while (parentFiber !== null) {
switch (parentFiber.tag) {
case HostRoot:
const root = parentFiber.stateNode;
root.passiveEffectDuration += passiveEffectDuration;
break outer;
case Profiler:
const parentStateNode = parentFiber.stateNode;
parentStateNode.passiveEffectDuration += passiveEffectDuration;
break outer;
}
parentFiber = parentFiber.return;
}
Expand Down Expand Up @@ -885,11 +890,16 @@ function commitLayoutEffectOnFiber(
// Propagate layout effect durations to the next nearest Profiler ancestor.
// Do not reset these values until the next render so DevTools has a chance to read them first.
let parentFiber = finishedWork.return;
while (parentFiber !== null) {
if (parentFiber.tag === Profiler) {
const parentStateNode = parentFiber.stateNode;
parentStateNode.effectDuration += effectDuration;
break;
outer: while (parentFiber !== null) {
switch (parentFiber.tag) {
case HostRoot:
const root = parentFiber.stateNode;
root.effectDuration += effectDuration;
break outer;
case Profiler:
const parentStateNode = parentFiber.stateNode;
parentStateNode.effectDuration += effectDuration;
break outer;
}
parentFiber = parentFiber.return;
}
Expand Down
7 changes: 7 additions & 0 deletions packages/react-reconciler/src/ReactFiberRoot.new.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ import {
enableSchedulerTracing,
enableSuspenseCallback,
enableCache,
enableProfilerCommitHooks,
enableProfilerTimer,
} from 'shared/ReactFeatureFlags';
import {unstable_getThreadID} from 'scheduler/tracing';
import {initializeUpdateQueue} from './ReactUpdateQueue.new';
Expand Down Expand Up @@ -71,6 +73,11 @@ function FiberRootNode(containerInfo, tag, hydrate) {
this.hydrationCallbacks = null;
}

if (enableProfilerTimer && enableProfilerCommitHooks) {
this.effectDuration = 0;
this.passiveEffectDuration = 0;
}

if (__DEV__) {
switch (tag) {
case ConcurrentRoot:
Expand Down
7 changes: 7 additions & 0 deletions packages/react-reconciler/src/ReactFiberRoot.old.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ import {
enableSchedulerTracing,
enableSuspenseCallback,
enableCache,
enableProfilerCommitHooks,
enableProfilerTimer,
} from 'shared/ReactFeatureFlags';
import {unstable_getThreadID} from 'scheduler/tracing';
import {initializeUpdateQueue} from './ReactUpdateQueue.old';
Expand Down Expand Up @@ -71,6 +73,11 @@ function FiberRootNode(containerInfo, tag, hydrate) {
this.hydrationCallbacks = null;
}

if (enableProfilerTimer && enableProfilerCommitHooks) {
this.effectDuration = 0;
this.passiveEffectDuration = 0;
}

if (__DEV__) {
switch (tag) {
case ConcurrentRoot:
Expand Down
46 changes: 30 additions & 16 deletions packages/react-reconciler/src/ReactProfilerTimer.new.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import {
enableProfilerNestedUpdatePhase,
enableProfilerTimer,
} from 'shared/ReactFeatureFlags';
import {Profiler} from './ReactWorkTags';
import {HostRoot, Profiler} from './ReactWorkTags';

// Intentionally not named imports because Rollup would use dynamic dispatch for
// CommonJS interop named imports.
Expand Down Expand Up @@ -140,13 +140,19 @@ function recordLayoutEffectDuration(fiber: Fiber): void {

layoutEffectStartTime = -1;

// Store duration on the next nearest Profiler ancestor.
// Store duration on the next nearest Profiler ancestor
// Or the root (for the DevTools Profiler to read)
let parentFiber = fiber.return;
while (parentFiber !== null) {
if (parentFiber.tag === Profiler) {
const parentStateNode = parentFiber.stateNode;
parentStateNode.effectDuration += elapsedTime;
break;
switch (parentFiber.tag) {
case HostRoot:
const root = parentFiber.stateNode;
root.effectDuration += elapsedTime;
return;
case Profiler:
const parentStateNode = parentFiber.stateNode;
parentStateNode.effectDuration += elapsedTime;
return;
}
parentFiber = parentFiber.return;
}
Expand All @@ -163,18 +169,26 @@ function recordPassiveEffectDuration(fiber: Fiber): void {

passiveEffectStartTime = -1;

// Store duration on the next nearest Profiler ancestor.
// Store duration on the next nearest Profiler ancestor
// Or the root (for the DevTools Profiler to read)
let parentFiber = fiber.return;
while (parentFiber !== null) {
if (parentFiber.tag === Profiler) {
const parentStateNode = parentFiber.stateNode;
if (parentStateNode !== null) {
// Detached fibers have their state node cleared out.
// In this case, the return pointer is also cleared out,
// so we won't be able to report the time spent in this Profiler's subtree.
parentStateNode.passiveEffectDuration += elapsedTime;
}
break;
switch (parentFiber.tag) {
case HostRoot:
const root = parentFiber.stateNode;
if (root !== null) {
root.passiveEffectDuration += elapsedTime;
}
return;
case Profiler:
const parentStateNode = parentFiber.stateNode;
if (parentStateNode !== null) {
// Detached fibers have their state node cleared out.
// In this case, the return pointer is also cleared out,
// so we won't be able to report the time spent in this Profiler's subtree.
parentStateNode.passiveEffectDuration += elapsedTime;
}
return;
}
parentFiber = parentFiber.return;
}
Expand Down
46 changes: 30 additions & 16 deletions packages/react-reconciler/src/ReactProfilerTimer.old.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import {
enableProfilerNestedUpdatePhase,
enableProfilerTimer,
} from 'shared/ReactFeatureFlags';
import {Profiler} from './ReactWorkTags';
import {HostRoot, Profiler} from './ReactWorkTags';

// Intentionally not named imports because Rollup would use dynamic dispatch for
// CommonJS interop named imports.
Expand Down Expand Up @@ -140,13 +140,19 @@ function recordLayoutEffectDuration(fiber: Fiber): void {

layoutEffectStartTime = -1;

// Store duration on the next nearest Profiler ancestor.
// Store duration on the next nearest Profiler ancestor
// Or the root (for the DevTools Profiler to read)
let parentFiber = fiber.return;
while (parentFiber !== null) {
if (parentFiber.tag === Profiler) {
const parentStateNode = parentFiber.stateNode;
parentStateNode.effectDuration += elapsedTime;
break;
switch (parentFiber.tag) {
case HostRoot:
const root = parentFiber.stateNode;
root.effectDuration += elapsedTime;
return;
case Profiler:
const parentStateNode = parentFiber.stateNode;
parentStateNode.effectDuration += elapsedTime;
return;
}
parentFiber = parentFiber.return;
}
Expand All @@ -163,18 +169,26 @@ function recordPassiveEffectDuration(fiber: Fiber): void {

passiveEffectStartTime = -1;

// Store duration on the next nearest Profiler ancestor.
// Store duration on the next nearest Profiler ancestor
// Or the root (for the DevTools Profiler to read)
let parentFiber = fiber.return;
while (parentFiber !== null) {
if (parentFiber.tag === Profiler) {
const parentStateNode = parentFiber.stateNode;
if (parentStateNode !== null) {
// Detached fibers have their state node cleared out.
// In this case, the return pointer is also cleared out,
// so we won't be able to report the time spent in this Profiler's subtree.
parentStateNode.passiveEffectDuration += elapsedTime;
}
break;
switch (parentFiber.tag) {
case HostRoot:
const root = parentFiber.stateNode;
if (root !== null) {
root.passiveEffectDuration += elapsedTime;
}
return;
case Profiler:
const parentStateNode = parentFiber.stateNode;
if (parentStateNode !== null) {
// Detached fibers have their state node cleared out.
// In this case, the return pointer is also cleared out,
// so we won't be able to report the time spent in this Profiler's subtree.
parentStateNode.passiveEffectDuration += elapsedTime;
}
return;
}
parentFiber = parentFiber.return;
}
Expand Down

0 comments on commit 466b26c

Please sign in to comment.