Skip to content

[DevTools][Transition Tracing] onTransitionComplete and onTransitionStart implmentation #23313

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 9 commits into from
Feb 24, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion packages/react-debug-tools/src/ReactDebugHooks.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import type {
MutableSourceSubscribeFn,
ReactContext,
ReactProviderType,
StartTransitionOptions,
} from 'shared/ReactTypes';
import type {
Fiber,
Expand Down Expand Up @@ -291,7 +292,10 @@ function useSyncExternalStore<T>(
return value;
}

function useTransition(): [boolean, (() => void) => void] {
function useTransition(): [
boolean,
(callback: () => void, options?: StartTransitionOptions) => void,
] {
// useTransition() composes multiple hooks internally.
// Advance the current hook index the same number of times
// so that subsequent hooks have the right memoized state.
Expand Down
10 changes: 9 additions & 1 deletion packages/react-reconciler/src/ReactFiberBeginWork.new.js
Original file line number Diff line number Diff line change
Expand Up @@ -226,6 +226,7 @@ import {
markSkippedUpdateLanes,
getWorkInProgressRoot,
pushRenderLanes,
getWorkInProgressTransitions,
} from './ReactFiberWorkLoop.new';
import {setWorkInProgressVersion} from './ReactMutableSource.new';
import {
Expand Down Expand Up @@ -1336,6 +1337,10 @@ function updateHostRoot(current, workInProgress, renderLanes) {
}
}

if (enableTransitionTracing) {
workInProgress.memoizedState.transitions = getWorkInProgressTransitions();
}

// Caution: React DevTools currently depends on this property
// being called "element".
const nextChildren = nextState.element;
Expand Down Expand Up @@ -3495,12 +3500,15 @@ function attemptEarlyBailoutIfNoScheduledUpdate(
switch (workInProgress.tag) {
case HostRoot:
pushHostRootContext(workInProgress);
const root: FiberRoot = workInProgress.stateNode;
if (enableCache) {
const root: FiberRoot = workInProgress.stateNode;
const cache: Cache = current.memoizedState.cache;
pushCacheProvider(workInProgress, cache);
pushRootCachePool(root);
}
if (enableTransitionTracing) {
workInProgress.memoizedState.transitions = getWorkInProgressTransitions();
}
resetHydrationState();
break;
case HostComponent:
Expand Down
10 changes: 9 additions & 1 deletion packages/react-reconciler/src/ReactFiberBeginWork.old.js
Original file line number Diff line number Diff line change
Expand Up @@ -226,6 +226,7 @@ import {
markSkippedUpdateLanes,
getWorkInProgressRoot,
pushRenderLanes,
getWorkInProgressTransitions,
} from './ReactFiberWorkLoop.old';
import {setWorkInProgressVersion} from './ReactMutableSource.old';
import {
Expand Down Expand Up @@ -1336,6 +1337,10 @@ function updateHostRoot(current, workInProgress, renderLanes) {
}
}

if (enableTransitionTracing) {
workInProgress.memoizedState.transitions = getWorkInProgressTransitions();
}

// Caution: React DevTools currently depends on this property
// being called "element".
const nextChildren = nextState.element;
Expand Down Expand Up @@ -3495,12 +3500,15 @@ function attemptEarlyBailoutIfNoScheduledUpdate(
switch (workInProgress.tag) {
case HostRoot:
pushHostRootContext(workInProgress);
const root: FiberRoot = workInProgress.stateNode;
if (enableCache) {
const root: FiberRoot = workInProgress.stateNode;
const cache: Cache = current.memoizedState.cache;
pushCacheProvider(workInProgress, cache);
pushRootCachePool(root);
}
if (enableTransitionTracing) {
workInProgress.memoizedState.transitions = getWorkInProgressTransitions();
}
resetHydrationState();
break;
case HostComponent:
Expand Down
50 changes: 43 additions & 7 deletions packages/react-reconciler/src/ReactFiberCommitWork.new.js
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ import {
enableSuspenseLayoutEffectSemantics,
enableUpdaterTracking,
enableCache,
enableTransitionTracing,
} from 'shared/ReactFeatureFlags';
import {
FunctionComponent,
Expand Down Expand Up @@ -132,6 +133,8 @@ import {
markCommitTimeOfFallback,
enqueuePendingPassiveProfilerEffect,
restorePendingUpdaters,
addTransitionStartCallbackToPendingTransition,
addTransitionCompleteCallbackToPendingTransition,
} from './ReactFiberWorkLoop.new';
import {
NoFlags as NoHookEffect,
Expand All @@ -156,6 +159,7 @@ import {
onCommitUnmount,
} from './ReactFiberDevToolsHook.new';
import {releaseCache, retainCache} from './ReactFiberCacheComponent.new';
import {clearTransitionsForLanes} from './ReactFiberLane.new';

let didWarnAboutUndefinedSnapshotBeforeUpdate: Set<mixed> | null = null;
if (__DEV__) {
Expand Down Expand Up @@ -983,8 +987,10 @@ function commitLayoutEffectOnFiber(
case IncompleteClassComponent:
case ScopeComponent:
case OffscreenComponent:
case LegacyHiddenComponent:
case LegacyHiddenComponent: {
break;
}

default:
throw new Error(
'This unit of work tag should not have side-effects. This error is ' +
Expand Down Expand Up @@ -2137,13 +2143,13 @@ export function commitMutationEffects(
inProgressRoot = root;
nextEffect = firstChild;

commitMutationEffects_begin(root);
commitMutationEffects_begin(root, committedLanes);

inProgressLanes = null;
inProgressRoot = null;
}

function commitMutationEffects_begin(root: FiberRoot) {
function commitMutationEffects_begin(root: FiberRoot, lanes: Lanes) {
while (nextEffect !== null) {
const fiber = nextEffect;

Expand All @@ -2166,17 +2172,17 @@ function commitMutationEffects_begin(root: FiberRoot) {
ensureCorrectReturnPointer(child, fiber);
nextEffect = child;
} else {
commitMutationEffects_complete(root);
commitMutationEffects_complete(root, lanes);
}
}
}

function commitMutationEffects_complete(root: FiberRoot) {
function commitMutationEffects_complete(root: FiberRoot, lanes: Lanes) {
while (nextEffect !== null) {
const fiber = nextEffect;
setCurrentDebugFiberInDEV(fiber);
try {
commitMutationEffectsOnFiber(fiber, root);
commitMutationEffectsOnFiber(fiber, root, lanes);
} catch (error) {
reportUncaughtErrorInDEV(error);
captureCommitPhaseError(fiber, fiber.return, error);
Expand All @@ -2194,13 +2200,43 @@ function commitMutationEffects_complete(root: FiberRoot) {
}
}

function commitMutationEffectsOnFiber(finishedWork: Fiber, root: FiberRoot) {
function commitMutationEffectsOnFiber(
finishedWork: Fiber,
root: FiberRoot,
lanes: Lanes,
) {
// TODO: The factoring of this phase could probably be improved. Consider
// switching on the type of work before checking the flags. That's what
// we do in all the other phases. I think this one is only different
// because of the shared reconciliation logic below.
const flags = finishedWork.flags;

if (enableTransitionTracing) {
switch (finishedWork.tag) {
case HostRoot: {
const state = finishedWork.memoizedState;
const transitions = state.transitions;
if (transitions !== null) {
transitions.forEach(transition => {
// TODO(luna) Do we want to log TransitionStart in the startTransition callback instead?
addTransitionStartCallbackToPendingTransition({
transitionName: transition.name,
startTime: transition.startTime,
});

addTransitionCompleteCallbackToPendingTransition({
transitionName: transition.name,
startTime: transition.startTime,
});
});

clearTransitionsForLanes(root, lanes);
state.transitions = null;
}
}
}
}

if (flags & ContentReset) {
commitResetTextContent(finishedWork);
}
Expand Down
50 changes: 43 additions & 7 deletions packages/react-reconciler/src/ReactFiberCommitWork.old.js
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ import {
enableSuspenseLayoutEffectSemantics,
enableUpdaterTracking,
enableCache,
enableTransitionTracing,
} from 'shared/ReactFeatureFlags';
import {
FunctionComponent,
Expand Down Expand Up @@ -132,6 +133,8 @@ import {
markCommitTimeOfFallback,
enqueuePendingPassiveProfilerEffect,
restorePendingUpdaters,
addTransitionStartCallbackToPendingTransition,
addTransitionCompleteCallbackToPendingTransition,
} from './ReactFiberWorkLoop.old';
import {
NoFlags as NoHookEffect,
Expand All @@ -156,6 +159,7 @@ import {
onCommitUnmount,
} from './ReactFiberDevToolsHook.old';
import {releaseCache, retainCache} from './ReactFiberCacheComponent.old';
import {clearTransitionsForLanes} from './ReactFiberLane.old';

let didWarnAboutUndefinedSnapshotBeforeUpdate: Set<mixed> | null = null;
if (__DEV__) {
Expand Down Expand Up @@ -983,8 +987,10 @@ function commitLayoutEffectOnFiber(
case IncompleteClassComponent:
case ScopeComponent:
case OffscreenComponent:
case LegacyHiddenComponent:
case LegacyHiddenComponent: {
break;
}

default:
throw new Error(
'This unit of work tag should not have side-effects. This error is ' +
Expand Down Expand Up @@ -2137,13 +2143,13 @@ export function commitMutationEffects(
inProgressRoot = root;
nextEffect = firstChild;

commitMutationEffects_begin(root);
commitMutationEffects_begin(root, committedLanes);

inProgressLanes = null;
inProgressRoot = null;
}

function commitMutationEffects_begin(root: FiberRoot) {
function commitMutationEffects_begin(root: FiberRoot, lanes: Lanes) {
while (nextEffect !== null) {
const fiber = nextEffect;

Expand All @@ -2166,17 +2172,17 @@ function commitMutationEffects_begin(root: FiberRoot) {
ensureCorrectReturnPointer(child, fiber);
nextEffect = child;
} else {
commitMutationEffects_complete(root);
commitMutationEffects_complete(root, lanes);
}
}
}

function commitMutationEffects_complete(root: FiberRoot) {
function commitMutationEffects_complete(root: FiberRoot, lanes: Lanes) {
while (nextEffect !== null) {
const fiber = nextEffect;
setCurrentDebugFiberInDEV(fiber);
try {
commitMutationEffectsOnFiber(fiber, root);
commitMutationEffectsOnFiber(fiber, root, lanes);
} catch (error) {
reportUncaughtErrorInDEV(error);
captureCommitPhaseError(fiber, fiber.return, error);
Expand All @@ -2194,13 +2200,43 @@ function commitMutationEffects_complete(root: FiberRoot) {
}
}

function commitMutationEffectsOnFiber(finishedWork: Fiber, root: FiberRoot) {
function commitMutationEffectsOnFiber(
finishedWork: Fiber,
root: FiberRoot,
lanes: Lanes,
) {
// TODO: The factoring of this phase could probably be improved. Consider
// switching on the type of work before checking the flags. That's what
// we do in all the other phases. I think this one is only different
// because of the shared reconciliation logic below.
const flags = finishedWork.flags;

if (enableTransitionTracing) {
switch (finishedWork.tag) {
case HostRoot: {
const state = finishedWork.memoizedState;
const transitions = state.transitions;
if (transitions !== null) {
transitions.forEach(transition => {
// TODO(luna) Do we want to log TransitionStart in the startTransition callback instead?
addTransitionStartCallbackToPendingTransition({
transitionName: transition.name,
startTime: transition.startTime,
});

addTransitionCompleteCallbackToPendingTransition({
transitionName: transition.name,
startTime: transition.startTime,
});
});

clearTransitionsForLanes(root, lanes);
state.transitions = null;
}
}
}
}

if (flags & ContentReset) {
commitResetTextContent(finishedWork);
}
Expand Down
11 changes: 10 additions & 1 deletion packages/react-reconciler/src/ReactFiberCompleteWork.new.js
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ import {
OffscreenComponent,
LegacyHiddenComponent,
CacheComponent,
TracingMarkerComponent,
} from './ReactWorkTags';
import {NoMode, ConcurrentMode, ProfileMode} from './ReactTypeOfMode';
import {
Expand Down Expand Up @@ -141,6 +142,7 @@ import {
enableCache,
enableSuspenseLayoutEffectSemantics,
enablePersistentOffscreenHostContainer,
enableTransitionTracing,
} from 'shared/ReactFeatureFlags';
import {
renderDidSuspend,
Expand Down Expand Up @@ -1570,8 +1572,15 @@ function completeWork(
}
popCacheProvider(workInProgress, cache);
bubbleProperties(workInProgress);
return null;
}
return null;
}
case TracingMarkerComponent: {
if (enableTransitionTracing) {
// Bubble subtree flags before so we can set the flag property
bubbleProperties(workInProgress);
}
return null;
}
}

Expand Down
11 changes: 10 additions & 1 deletion packages/react-reconciler/src/ReactFiberCompleteWork.old.js
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ import {
OffscreenComponent,
LegacyHiddenComponent,
CacheComponent,
TracingMarkerComponent,
} from './ReactWorkTags';
import {NoMode, ConcurrentMode, ProfileMode} from './ReactTypeOfMode';
import {
Expand Down Expand Up @@ -141,6 +142,7 @@ import {
enableCache,
enableSuspenseLayoutEffectSemantics,
enablePersistentOffscreenHostContainer,
enableTransitionTracing,
} from 'shared/ReactFeatureFlags';
import {
renderDidSuspend,
Expand Down Expand Up @@ -1570,8 +1572,15 @@ function completeWork(
}
popCacheProvider(workInProgress, cache);
bubbleProperties(workInProgress);
return null;
}
return null;
}
case TracingMarkerComponent: {
if (enableTransitionTracing) {
// Bubble subtree flags before so we can set the flag property
bubbleProperties(workInProgress);
}
return null;
}
}

Expand Down
Loading