Skip to content

Commit

Permalink
Add Profiler callback when nested udpates are scheduled
Browse files Browse the repository at this point in the history
  • Loading branch information
Brian Vaughn committed Nov 10, 2020
1 parent 393c452 commit abfccea
Show file tree
Hide file tree
Showing 13 changed files with 617 additions and 0 deletions.
38 changes: 38 additions & 0 deletions packages/react-reconciler/src/ReactFiberWorkLoop.new.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import {
replayFailedUnitOfWorkWithInvokeGuardedCallback,
enableProfilerTimer,
enableProfilerNestedUpdatePhase,
enableProfilerNestedUpdateScheduledHook,
enableSchedulerTracing,
warnAboutUnmockedScheduler,
deferRenderPhaseUpdateToNextBatch,
Expand Down Expand Up @@ -110,6 +111,7 @@ import {
ForwardRef,
MemoComponent,
SimpleMemoComponent,
Profiler,
} from './ReactWorkTags';
import {LegacyRoot} from './ReactRootTags';
import {
Expand Down Expand Up @@ -258,6 +260,10 @@ let workInProgress: Fiber | null = null;
// The lanes we're rendering
let workInProgressRootRenderLanes: Lanes = NoLanes;

// Only used when enableProfilerNestedUpdateScheduledHook is true;
// to track which root is currently committing layout effects.
let rootCommittingMutationOrLayoutEffects: FiberRoot | null = null;

// Stack that allows components to change the render lanes for its subtree
// This is a superset of the lanes we started working on at the root. The only
// case where it's different from `workInProgressRootRenderLanes` is when we
Expand Down Expand Up @@ -509,6 +515,30 @@ export function scheduleUpdateOnFiber(
// Mark that the root has a pending update.
markRootUpdated(root, lane, eventTime);

if (enableProfilerNestedUpdateScheduledHook) {
if (
executionContext === CommitContext &&
root === rootCommittingMutationOrLayoutEffects
) {
if (fiber.mode & ProfileMode) {
let current = fiber;
while (current !== null) {
if (current.tag === Profiler) {
const {onNestedUpdateScheduled} = current.memoizedProps;
if (typeof onNestedUpdateScheduled === 'function') {
if (enableSchedulerTracing) {
onNestedUpdateScheduled(fiber.type, root.memoizedInteractions);
} else {
onNestedUpdateScheduled(fiber.type);
}
}
}
current = current.return;
}
}
}
}

if (root === workInProgressRoot) {
// Received an update to a tree that's in the middle of rendering. Mark
// that there was an interleaved update work on this root. Unless the
Expand Down Expand Up @@ -1898,6 +1928,10 @@ function commitRootImpl(root, renderPriorityLevel) {
recordCommitTime();
}

if (enableProfilerNestedUpdateScheduledHook) {
rootCommittingMutationOrLayoutEffects = root;
}

// The next phase is the mutation phase, where we mutate the host tree.
commitMutationEffects(finishedWork, root, renderPriorityLevel);

Expand Down Expand Up @@ -1936,6 +1970,10 @@ function commitRootImpl(root, renderPriorityLevel) {
markLayoutEffectsStopped();
}

if (enableProfilerNestedUpdateScheduledHook) {
rootCommittingMutationOrLayoutEffects = null;
}

// Tell Scheduler to yield at the end of the frame, so the browser has an
// opportunity to paint.
requestPaint();
Expand Down
40 changes: 40 additions & 0 deletions packages/react-reconciler/src/ReactFiberWorkLoop.old.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import {
enableProfilerTimer,
enableProfilerCommitHooks,
enableProfilerNestedUpdatePhase,
enableProfilerNestedUpdateScheduledHook,
enableSchedulerTracing,
warnAboutUnmockedScheduler,
deferRenderPhaseUpdateToNextBatch,
Expand Down Expand Up @@ -112,6 +113,7 @@ import {
OffscreenComponent,
LegacyHiddenComponent,
ScopeComponent,
Profiler,
} from './ReactWorkTags';
import {LegacyRoot} from './ReactRootTags';
import {
Expand Down Expand Up @@ -329,6 +331,10 @@ let hasUncaughtError = false;
let firstUncaughtError = null;
let legacyErrorBoundariesThatAlreadyFailed: Set<mixed> | null = null;

// Only used when enableProfilerNestedUpdateScheduledHook is true;
// to track which root is currently committing layout effects.
let rootCommittingMutationOrLayoutEffects: FiberRoot | null = null;

let rootDoesHavePassiveEffects: boolean = false;
let rootWithPendingPassiveEffects: FiberRoot | null = null;
let pendingPassiveEffectsRenderPriority: ReactPriorityLevel = NoSchedulerPriority;
Expand Down Expand Up @@ -533,6 +539,30 @@ export function scheduleUpdateOnFiber(
// Mark that the root has a pending update.
markRootUpdated(root, lane, eventTime);

if (enableProfilerNestedUpdateScheduledHook) {
if (
executionContext === CommitContext &&
root === rootCommittingMutationOrLayoutEffects
) {
if (fiber.mode & ProfileMode) {
let current = fiber;
while (current !== null) {
if (current.tag === Profiler) {
const {onNestedUpdateScheduled} = current.memoizedProps;
if (typeof onNestedUpdateScheduled === 'function') {
if (enableSchedulerTracing) {
onNestedUpdateScheduled(fiber.type, root.memoizedInteractions);
} else {
onNestedUpdateScheduled(fiber.type);
}
}
}
current = current.return;
}
}
}
}

if (root === workInProgressRoot) {
// Received an update to a tree that's in the middle of rendering. Mark
// that there was an interleaved update work on this root. Unless the
Expand Down Expand Up @@ -2047,6 +2077,12 @@ function commitRootImpl(root, renderPriorityLevel) {
recordCommitTime();
}

if (enableProfilerNestedUpdateScheduledHook) {
// Track the root here, rather than in commitLayoutEffects(), because of ref setters.
// Updates scheduled during ref detachment should also be flagged.
rootCommittingMutationOrLayoutEffects = root;
}

// The next phase is the mutation phase, where we mutate the host tree.
nextEffect = firstEffect;
do {
Expand Down Expand Up @@ -2112,6 +2148,10 @@ function commitRootImpl(root, renderPriorityLevel) {

nextEffect = null;

if (enableProfilerNestedUpdateScheduledHook) {
rootCommittingMutationOrLayoutEffects = null;
}

// Tell Scheduler to yield at the end of the frame, so the browser has an
// opportunity to paint.
requestPaint();
Expand Down
Loading

0 comments on commit abfccea

Please sign in to comment.