Skip to content
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

[WIP][Transition Tracing] Transition Tracing API #23103

Closed
wants to merge 13 commits into from
12 changes: 12 additions & 0 deletions packages/react-art/src/ReactARTHostConfig.js
Original file line number Diff line number Diff line change
Expand Up @@ -451,3 +451,15 @@ export function preparePortalMount(portalInstance: any): void {
export function detachDeletedInstance(node: Instance): void {
// noop
}

export function getCurrentEventStartTime() {
// noop
}

export function scheduleTransitionCallbacks(
callback,
pendingTransitions,
callbacks,
) {
// noop
}
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 @@ -290,7 +291,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
51 changes: 50 additions & 1 deletion packages/react-dom/src/client/ReactDOMHostConfig.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,18 @@
*/

import type {DOMEventName} from '../events/DOMEventNames';
import type {Fiber, FiberRoot} from 'react-reconciler/src/ReactInternalTypes';
import type {
Fiber,
FiberRoot,
TransitionTracingCallbacks,
} from 'react-reconciler/src/ReactInternalTypes';
import type {
BoundingRect,
IntersectionObserverOptions,
ObserveVisibleRectsCallback,
} from 'react-reconciler/src/ReactTestSelectors';
import type {ReactScopeInstance} from 'shared/ReactTypes';
import type {TransitionCallbackObject} from 'react-reconciler/src/ReactFiberTracingMarkerComponent.new';

import {
precacheFiberNode,
Expand Down Expand Up @@ -70,6 +75,11 @@ import {HostComponent, HostText} from 'react-reconciler/src/ReactWorkTags';
import {listenToAllSupportedEvents} from '../events/DOMPluginEventSystem';

import {DefaultEventPriority} from 'react-reconciler/src/ReactEventPriorities';
import {
now,
scheduleCallback,
IdlePriority,
} from 'react-reconciler/src/Scheduler';

export type Type = string;
export type Props = {
Expand Down Expand Up @@ -1243,3 +1253,42 @@ export function setupIntersectionObserver(
},
};
}

let currentFrameTime = null;
export function getCurrentEventStartTime(): number {
const event = window.event;
if (event != null) {
return event.timeStamp;
}

if (currentFrameTime === null) {
currentFrameTime = performance.now();

setTimeout(() => {
currentFrameTime = null;
}, 0);
}

return currentFrameTime;
}

// TODO(luna) Fix this because rAF doesn't actually do
// what you want here
export function scheduleTransitionCallbacks(
callback: (
Array<TransitionCallbackObject>,
endTime: number,
callbacks: TransitionTracingCallbacks,
) => void,
// TODO(luna) Figure out type of this
pendingTransitions: Array<TransitionCallbackObject>,
callbacks: TransitionTracingCallbacks,
): void {
window.requestAnimationFrame(() => {
const endTime = now();

scheduleCallback(IdlePriority, () => {
callback(pendingTransitions, endTime, callbacks);
});
});
}
27 changes: 26 additions & 1 deletion packages/react-dom/src/events/ReactDOMEventListener.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,10 @@ import type {AnyNativeEvent} from '../events/PluginModuleType';
import type {FiberRoot} from 'react-reconciler/src/ReactInternalTypes';
import type {Container, SuspenseInstance} from '../client/ReactDOMHostConfig';
import type {DOMEventName} from '../events/DOMEventNames';
import {enableCapturePhaseSelectiveHydrationWithoutDiscreteEventReplay} from 'shared/ReactFeatureFlags';
import {
enableCapturePhaseSelectiveHydrationWithoutDiscreteEventReplay,
enableTransitionTracing,
} from 'shared/ReactFeatureFlags';
import {
isDiscreteEventThatRequiresHydration,
queueDiscreteEvent,
Expand Down Expand Up @@ -118,12 +121,23 @@ function dispatchDiscreteEvent(
const previousPriority = getCurrentUpdatePriority();
const prevTransition = ReactCurrentBatchConfig.transition;
ReactCurrentBatchConfig.transition = 0;

let prevTransitionInfo = null;
if (enableTransitionTracing) {
prevTransitionInfo = ReactCurrentBatchConfig.transitionInfo;
ReactCurrentBatchConfig.transitionInfo = null;
}

try {
setCurrentUpdatePriority(DiscreteEventPriority);
dispatchEvent(domEventName, eventSystemFlags, container, nativeEvent);
} finally {
setCurrentUpdatePriority(previousPriority);
ReactCurrentBatchConfig.transition = prevTransition;

if (enableTransitionTracing) {
ReactCurrentBatchConfig.transitionInfo = prevTransitionInfo;
}
}
}

Expand All @@ -136,12 +150,23 @@ function dispatchContinuousEvent(
const previousPriority = getCurrentUpdatePriority();
const prevTransition = ReactCurrentBatchConfig.transition;
ReactCurrentBatchConfig.transition = 0;

let prevTransitionInfo = null;
if (enableTransitionTracing) {
prevTransitionInfo = ReactCurrentBatchConfig.transitionInfo;
ReactCurrentBatchConfig.transitionInfo = null;
}

try {
setCurrentUpdatePriority(ContinuousEventPriority);
dispatchEvent(domEventName, eventSystemFlags, container, nativeEvent);
} finally {
setCurrentUpdatePriority(previousPriority);
ReactCurrentBatchConfig.transition = prevTransition;

if (enableTransitionTracing) {
ReactCurrentBatchConfig.transitionInfo = prevTransitionInfo;
}
}
}

Expand Down
12 changes: 12 additions & 0 deletions packages/react-native-renderer/src/ReactFabricHostConfig.js
Original file line number Diff line number Diff line change
Expand Up @@ -525,3 +525,15 @@ export function preparePortalMount(portalInstance: Instance): void {
export function detachDeletedInstance(node: Instance): void {
// noop
}

export function getCurrentEventStartTime() {
// noop
}

export function scheduleTransitionCallbacks(
callback,
pendingTransitions,
callbacks,
) {
// noop
}
12 changes: 12 additions & 0 deletions packages/react-native-renderer/src/ReactNativeHostConfig.js
Original file line number Diff line number Diff line change
Expand Up @@ -513,3 +513,15 @@ export function preparePortalMount(portalInstance: Instance): void {
export function detachDeletedInstance(node: Instance): void {
// noop
}

export function getCurrentEventStartTime() {
// noop
}

export function scheduleTransitionCallbacks(
callback,
pendingTransitions,
callbacks,
) {
// noop
}
20 changes: 20 additions & 0 deletions packages/react-noop-renderer/src/createReactNoop.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import type {
import type {UpdateQueue} from 'react-reconciler/src/ReactUpdateQueue';
import type {ReactNodeList, OffscreenMode} from 'shared/ReactTypes';
import type {RootTag} from 'react-reconciler/src/ReactRootTags';
import type {TransitionCallbackObject} from 'react-reconciler/src/ReactFiberTracingMarkerComponent.new';

import * as Scheduler from 'scheduler/unstable_mock';
import {REACT_FRAGMENT_TYPE, REACT_ELEMENT_TYPE} from 'shared/ReactSymbols';
Expand Down Expand Up @@ -477,6 +478,25 @@ function createReactNoop(reconciler: Function, useMutation: boolean) {
logRecoverableError() {
// no-op
},

getCurrentEventStartTime(): number {
return Scheduler.unstable_now();
},

scheduleTransitionCallbacks(
callback: (
Array<TransitionCallbackObject>,
endTime: number,
callbacks: TransitionTracingCallbacks,
) => void,
pendingTransitions: Array<TransitionCallbackObject>,
callbacks: TransitionTracingCallbacks,
): void {
const endTime = Scheduler.unstable_now();
Scheduler.unstable_scheduleCallback(Scheduler.unstable_IdlePriority, () =>
callback(pendingTransitions, endTime, callbacks),
);
},
};

const hostConfig = useMutation
Expand Down
Loading