Skip to content

Commit 8c67bbf

Browse files
authored
[scheduler] Deadline object -> shouldYield (#14025)
* [scheduler] Deadline object -> shouldYield Instead of using a requestIdleCallback-style deadline object, expose a method Scheduler.shouldYield that returns true if there's a higher priority event in the queue. * Nits
1 parent e02086b commit 8c67bbf

File tree

18 files changed

+215
-249
lines changed

18 files changed

+215
-249
lines changed

packages/react-art/src/ReactARTHostConfig.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
export {
99
unstable_now as now,
1010
unstable_scheduleCallback as scheduleDeferredCallback,
11+
unstable_shouldYield as shouldYield,
1112
unstable_cancelCallback as cancelDeferredCallback,
1213
} from 'scheduler';
1314
import Transform from 'art/core/transform';

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,7 @@ export type NoTimeout = -1;
6868
export {
6969
unstable_now as now,
7070
unstable_scheduleCallback as scheduleDeferredCallback,
71+
unstable_shouldYield as shouldYield,
7172
unstable_cancelCallback as cancelDeferredCallback,
7273
} from 'scheduler';
7374

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -332,6 +332,7 @@ export const scheduleDeferredCallback =
332332
ReactNativeFrameScheduling.scheduleDeferredCallback;
333333
export const cancelDeferredCallback =
334334
ReactNativeFrameScheduling.cancelDeferredCallback;
335+
export const shouldYield = ReactNativeFrameScheduling.shouldYield;
335336

336337
export const scheduleTimeout = setTimeout;
337338
export const cancelTimeout = clearTimeout;

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

Lines changed: 8 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -7,25 +7,16 @@
77
* @flow
88
*/
99

10-
import type {Deadline} from 'react-reconciler/src/ReactFiberScheduler';
11-
1210
const hasNativePerformanceNow =
1311
typeof performance === 'object' && typeof performance.now === 'function';
1412

1513
const now = hasNativePerformanceNow
1614
? () => performance.now()
1715
: () => Date.now();
1816

19-
type Callback = (deadline: Deadline) => void;
20-
21-
let scheduledCallback: Callback | null = null;
17+
let scheduledCallback: (() => mixed) | null = null;
2218
let frameDeadline: number = 0;
2319

24-
const frameDeadlineObject: Deadline = {
25-
timeRemaining: () => frameDeadline - now(),
26-
didTimeout: false,
27-
};
28-
2920
function setTimeoutCallback() {
3021
// TODO (bvaughn) Hard-coded 5ms unblocks initial async testing.
3122
// React API probably changing to boolean rather than time remaining.
@@ -36,15 +27,15 @@ function setTimeoutCallback() {
3627
const callback = scheduledCallback;
3728
scheduledCallback = null;
3829
if (callback !== null) {
39-
callback(frameDeadlineObject);
30+
callback();
4031
}
4132
}
4233

4334
// RN has a poor polyfill for requestIdleCallback so we aren't using it.
4435
// This implementation is only intended for short-term use anyway.
4536
// We also don't implement cancel functionality b'c Fiber doesn't currently need it.
4637
function scheduleDeferredCallback(
47-
callback: Callback,
38+
callback: () => mixed,
4839
options?: {timeout: number},
4940
): number {
5041
// We assume only one callback is scheduled at a time b'c that's how Fiber works.
@@ -58,4 +49,8 @@ function cancelDeferredCallback(callbackID: number) {
5849
clearTimeout((callbackID: any)); // Timeouts are always numbers on RN
5950
}
6051

61-
export {now, scheduleDeferredCallback, cancelDeferredCallback};
52+
function shouldYield() {
53+
return frameDeadline <= now();
54+
}
55+
56+
export {now, scheduleDeferredCallback, cancelDeferredCallback, shouldYield};

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -238,6 +238,7 @@ export const scheduleDeferredCallback =
238238
ReactNativeFrameScheduling.scheduleDeferredCallback;
239239
export const cancelDeferredCallback =
240240
ReactNativeFrameScheduling.cancelDeferredCallback;
241+
export const shouldYield = ReactNativeFrameScheduling.shouldYield;
241242

242243
export const scheduleTimeout = setTimeout;
243244
export const cancelTimeout = clearTimeout;

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

Lines changed: 37 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -319,7 +319,7 @@ function createReactNoop(reconciler: Function, useMutation: boolean) {
319319
scheduledCallbackTimeout === -1 ||
320320
scheduledCallbackTimeout > newTimeout
321321
) {
322-
scheduledCallbackTimeout = newTimeout;
322+
scheduledCallbackTimeout = elapsedTimeInMs + newTimeout;
323323
}
324324
}
325325
return 0;
@@ -333,6 +333,8 @@ function createReactNoop(reconciler: Function, useMutation: boolean) {
333333
scheduledCallbackTimeout = -1;
334334
},
335335

336+
shouldYield,
337+
336338
scheduleTimeout: setTimeout,
337339
cancelTimeout: clearTimeout,
338340
noTimeout: -1,
@@ -512,35 +514,44 @@ function createReactNoop(reconciler: Function, useMutation: boolean) {
512514

513515
let yieldedValues = null;
514516

517+
let didYield;
515518
let unitsRemaining;
516519

517-
function* flushUnitsOfWork(n: number): Generator<Array<mixed>, void, void> {
518-
let didStop = false;
519-
while (!didStop && scheduledCallback !== null) {
520-
let cb = scheduledCallback;
521-
scheduledCallback = null;
522-
unitsRemaining = n;
523-
cb({
524-
timeRemaining() {
525-
if (yieldedValues !== null) {
526-
return 0;
527-
}
528-
if (unitsRemaining-- > 0) {
529-
return 999;
530-
}
531-
didStop = true;
532-
return 0;
533-
},
534-
didTimeout:
535-
scheduledCallbackTimeout !== -1 &&
536-
elapsedTimeInMs > scheduledCallbackTimeout,
537-
});
520+
function shouldYield() {
521+
if (
522+
scheduledCallbackTimeout === -1 ||
523+
elapsedTimeInMs > scheduledCallbackTimeout
524+
) {
525+
return false;
526+
} else {
527+
if (didYield || yieldedValues !== null) {
528+
return true;
529+
}
530+
if (unitsRemaining-- > 0) {
531+
return false;
532+
}
533+
didYield = true;
534+
return true;
535+
}
536+
}
538537

539-
if (yieldedValues !== null) {
540-
const values = yieldedValues;
541-
yieldedValues = null;
542-
yield values;
538+
function* flushUnitsOfWork(n: number): Generator<Array<mixed>, void, void> {
539+
unitsRemaining = n + 1;
540+
didYield = false;
541+
try {
542+
while (!didYield && scheduledCallback !== null) {
543+
let cb = scheduledCallback;
544+
scheduledCallback = null;
545+
cb();
546+
if (yieldedValues !== null) {
547+
const values = yieldedValues;
548+
yieldedValues = null;
549+
yield values;
550+
}
543551
}
552+
} finally {
553+
unitsRemaining = -1;
554+
didYield = false;
544555
}
545556
}
546557

0 commit comments

Comments
 (0)