Skip to content

Commit eb94785

Browse files
committed
end time
1 parent d0f3966 commit eb94785

File tree

10 files changed

+123
-17
lines changed

10 files changed

+123
-17
lines changed

packages/react-art/src/ReactARTHostConfig.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -451,3 +451,7 @@ export function preparePortalMount(portalInstance: any): void {
451451
export function detachDeletedInstance(node: Instance): void {
452452
// noop
453453
}
454+
455+
export function requestPostPaintCallback(callback: (time: number) => void) {
456+
// noop
457+
}

packages/react-dom/src/client/ReactDOMHostConfig.js

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1379,3 +1379,9 @@ export function setupIntersectionObserver(
13791379
},
13801380
};
13811381
}
1382+
1383+
export function requestPostPaintCallback(callback: (time: number) => void) {
1384+
requestAnimationFrame(() => {
1385+
requestAnimationFrame(time => callback(time));
1386+
});
1387+
}

packages/react-native-renderer/src/ReactFabricHostConfig.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -609,3 +609,7 @@ export function preparePortalMount(portalInstance: Instance): void {
609609
export function detachDeletedInstance(node: Instance): void {
610610
// noop
611611
}
612+
613+
export function requestPostPaintCallback(callback: (time: number) => void) {
614+
// noop
615+
}

packages/react-native-renderer/src/ReactNativeHostConfig.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -510,3 +510,7 @@ export function preparePortalMount(portalInstance: Instance): void {
510510
export function detachDeletedInstance(node: Instance): void {
511511
// noop
512512
}
513+
514+
export function requestPostPaintCallback(callback: (time: number) => void) {
515+
// noop
516+
}

packages/react-noop-renderer/src/createReactNoop.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -473,6 +473,11 @@ function createReactNoop(reconciler: Function, useMutation: boolean) {
473473
logRecoverableError() {
474474
// no-op
475475
},
476+
477+
requestPostPaintCallback(callback) {
478+
const endTime = Scheduler.unstable_now();
479+
callback(endTime);
480+
},
476481
};
477482

478483
const hostConfig = useMutation

packages/react-reconciler/src/ReactFiberHostConfigWithNoMutation.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,3 +35,4 @@ export const hideTextInstance = shim;
3535
export const unhideInstance = shim;
3636
export const unhideTextInstance = shim;
3737
export const clearContainer = shim;
38+
export const requestPostPaintCallback = shim;

packages/react-reconciler/src/ReactFiberWorkLoop.new.js

Lines changed: 32 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,7 @@ import {
8282
supportsMicrotasks,
8383
errorHydratingContainer,
8484
scheduleMicrotask,
85+
requestPostPaintCallback,
8586
} from './ReactFiberHostConfig';
8687

8788
import {
@@ -350,6 +351,7 @@ export function getWorkInProgressTransitions() {
350351
}
351352

352353
let currentPendingTransitionCallbacks: PendingTransitionCallbacks | null = null;
354+
let currentEndTime: number | null = null;
353355

354356
export function addTransitionStartCallbackToPendingTransition(
355357
transition: Transition,
@@ -2514,6 +2516,24 @@ function commitRootImpl(
25142516
markCommitStopped();
25152517
}
25162518

2519+
const prevRootTransitionCallbacks = root.transitionCallbacks;
2520+
if (prevRootTransitionCallbacks !== null) {
2521+
requestPostPaintCallback(endTime => {
2522+
const prevPendingTransitionCallbacks = currentPendingTransitionCallbacks;
2523+
if (prevPendingTransitionCallbacks !== null) {
2524+
scheduleCallback(IdleSchedulerPriority, () => {
2525+
processTransitionCallbacks(
2526+
prevPendingTransitionCallbacks,
2527+
endTime,
2528+
prevRootTransitionCallbacks,
2529+
);
2530+
});
2531+
} else {
2532+
currentEndTime = endTime;
2533+
}
2534+
});
2535+
}
2536+
25172537
return null;
25182538
}
25192539

@@ -2655,28 +2675,23 @@ function flushPassiveEffectsImpl() {
26552675
if (enableTransitionTracing) {
26562676
const prevPendingTransitionCallbacks = currentPendingTransitionCallbacks;
26572677
const prevRootTransitionCallbacks = root.transitionCallbacks;
2678+
const prevEndTime = currentEndTime;
26582679
if (
26592680
prevPendingTransitionCallbacks !== null &&
26602681
prevRootTransitionCallbacks !== null
26612682
) {
2662-
// TODO(luna) Refactor this code into the Host Config
2663-
// TODO(luna) The end time here is not necessarily accurate
2664-
// because passive effects could be called before paint
2665-
// (synchronously) or after paint (normally). We need
2666-
// to come up with a way to get the correct end time for both cases.
2667-
// One solution is in the host config, if the passive effects
2668-
// have not yet been run, make a call to flush the passive effects
2669-
// right after paint.
2670-
const endTime = now();
26712683
currentPendingTransitionCallbacks = null;
2672-
2673-
scheduleCallback(IdleSchedulerPriority, () =>
2674-
processTransitionCallbacks(
2675-
prevPendingTransitionCallbacks,
2676-
endTime,
2677-
prevRootTransitionCallbacks,
2678-
),
2679-
);
2684+
currentEndTime = null;
2685+
2686+
if (prevEndTime !== null) {
2687+
scheduleCallback(IdleSchedulerPriority, () =>
2688+
processTransitionCallbacks(
2689+
prevPendingTransitionCallbacks,
2690+
prevEndTime,
2691+
prevRootTransitionCallbacks,
2692+
),
2693+
);
2694+
}
26802695
}
26812696
}
26822697

packages/react-reconciler/src/__tests__/ReactTransitionTracing-test.js

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1434,4 +1434,66 @@ describe('ReactInteractionTracing', () => {
14341434
});
14351435
expect(Scheduler).toHaveYielded(['Hidden Text']);
14361436
});
1437+
1438+
// @gate enableTransitionTracing
1439+
it('discrete events', async () => {
1440+
const transitionCallbacks = {
1441+
onTransitionStart: (name, startTime) => {
1442+
Scheduler.unstable_yieldValue(
1443+
`onTransitionStart(${name}, ${startTime})`,
1444+
);
1445+
},
1446+
onTransitionProgress: (name, startTime, endTime, pending) => {
1447+
const suspenseNames = pending.map(p => p.name || '<null>').join(', ');
1448+
Scheduler.unstable_yieldValue(
1449+
`onTransitionProgress(${name}, ${startTime}, ${endTime}, [${suspenseNames}])`,
1450+
);
1451+
},
1452+
onTransitionComplete: (name, startTime, endTime) => {
1453+
Scheduler.unstable_yieldValue(
1454+
`onTransitionComplete(${name}, ${startTime}, ${endTime})`,
1455+
);
1456+
},
1457+
};
1458+
1459+
function App() {
1460+
return (
1461+
<Suspense
1462+
fallback={<Text text="Loading..." />}
1463+
unstable_name="suspense page">
1464+
<AsyncText text="Page Two" />
1465+
</Suspense>
1466+
);
1467+
}
1468+
1469+
const root = ReactNoop.createRoot({
1470+
unstable_transitionCallbacks: transitionCallbacks,
1471+
});
1472+
1473+
await act(async () => {
1474+
ReactNoop.discreteUpdates(() =>
1475+
startTransition(() => root.render(<App />), {name: 'page transition'}),
1476+
);
1477+
ReactNoop.expire(1000);
1478+
await advanceTimers(1000);
1479+
});
1480+
1481+
expect(Scheduler).toHaveYielded([
1482+
'Suspend [Page Two]',
1483+
'Loading...',
1484+
'onTransitionStart(page transition, 0)',
1485+
'onTransitionProgress(page transition, 0, 1000, [suspense page])',
1486+
]);
1487+
await act(async () => {
1488+
ReactNoop.discreteUpdates(() => resolveText('Page Two'));
1489+
ReactNoop.expire(1000);
1490+
await advanceTimers(1000);
1491+
});
1492+
1493+
expect(Scheduler).toHaveYielded([
1494+
'Page Two',
1495+
'onTransitionProgress(page transition, 0, 2000, [])',
1496+
'onTransitionComplete(page transition, 0, 2000)',
1497+
]);
1498+
});
14371499
});

packages/react-reconciler/src/forks/ReactFiberHostConfig.custom.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@ export const prepareScopeUpdate = $$$hostConfig.prepareScopeUpdate;
6767
export const getInstanceFromScope = $$$hostConfig.getInstanceFromScope;
6868
export const getCurrentEventPriority = $$$hostConfig.getCurrentEventPriority;
6969
export const detachDeletedInstance = $$$hostConfig.detachDeletedInstance;
70+
export const requestPostPaintCallback = $$$hostConfig.requestPostPaintCallback;
7071

7172
// -------------------
7273
// Microtasks

packages/react-test-renderer/src/ReactTestHostConfig.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -317,3 +317,7 @@ export function detachDeletedInstance(node: Instance): void {
317317
export function logRecoverableError(error: mixed): void {
318318
// noop
319319
}
320+
321+
export function requestPostPaintCallback(callback: (time: number) => void) {
322+
// noop
323+
}

0 commit comments

Comments
 (0)