@samitouri / QOS-React-2 / commits / b00e27342d

Use native scheduler if defined in global scope (#26554)

Co-authored-by: Dan Abramov <dan.abramov@gmail.com>

Samuel Susla committed May 5, 2023 at 14:01 UTC b00e27342d6ff0f2a3a57b8e1edf66290d27cf07
7 files changed +147 -2
packages/scheduler/index.native.js new
+12
@@ -0,0 +1,12 @@
1 +/**
2 + * Copyright (c) Meta Platforms, Inc. and affiliates.
3 + *
4 + * This source code is licensed under the MIT license found in the
5 + * LICENSE file in the root directory of this source tree.
6 + *
7 + * @flow
8 + */
9 +
10 +'use strict';
11 +
12 +export * from './src/forks/SchedulerNative';
packages/scheduler/npm/index.native.js new
+7
@@ -0,0 +1,7 @@
1 +'use strict';
2 +
3 +if (process.env.NODE_ENV === 'production') {
4 + module.exports = require('./cjs/scheduler.native.production.min.js');
5 +} else {
6 + module.exports = require('./cjs/scheduler.native.development.js');
7 +}
packages/scheduler/package.json
+1 -1
@@ -2,7 +2,6 @@
2 "name": "scheduler",
3 "version": "0.23.0",
4 "description": "Cooperative scheduler for the browser environment.",
5 - "main": "index.js",
5 "repository": {
6 "type": "git",
7 "url": "https://github.com/facebook/react.git",
@@ -23,6 +22,7 @@
22 "LICENSE",
23 "README.md",
24 "index.js",
25 + "index.native.js",
26 "unstable_mock.js",
27 "unstable_post_task.js",
28 "cjs/",
packages/scheduler/src/forks/Scheduler.js
+1 -1
@@ -46,7 +46,7 @@ import {
46
47 export type Callback = boolean => ?Callback;
48
49 -type Task = {
49 +export opaque type Task = {
50 id: number,
51 callback: Callback | null,
52 priorityLevel: PriorityLevel,
packages/scheduler/src/forks/SchedulerNative.js new
+112
@@ -0,0 +1,112 @@
1 +/**
2 + * Copyright (c) Meta Platforms, Inc. and affiliates.
3 + *
4 + * This source code is licensed under the MIT license found in the
5 + * LICENSE file in the root directory of this source tree.
6 + *
7 + * @flow strict
8 + */
9 +
10 +import * as Scheduler from './Scheduler';
11 +import type {Callback, Task} from './Scheduler';
12 +import type {PriorityLevel} from '../SchedulerPriorities';
13 +import typeof * as SchedulerExportsType from './Scheduler';
14 +import typeof * as SchedulerNativeExportsType from './SchedulerNative';
15 +
16 +// This type is supposed to reflect the actual methods and arguments currently supported by the C++ implementation:
17 +// https://github.com/facebook/react-native/blob/main/packages/react-native/ReactCommon/react/renderer/runtimescheduler/RuntimeSchedulerBinding.cpp
18 +type NativeSchedulerType = {
19 + unstable_ImmediatePriority: PriorityLevel,
20 + unstable_UserBlockingPriority: PriorityLevel,
21 + unstable_NormalPriority: PriorityLevel,
22 + unstable_IdlePriority: PriorityLevel,
23 + unstable_LowPriority: PriorityLevel,
24 + unstable_scheduleCallback: (
25 + priorityLevel: PriorityLevel,
26 + callback: Callback,
27 + ) => Task,
28 + unstable_cancelCallback: (task: Task) => void,
29 + unstable_getCurrentPriorityLevel: () => PriorityLevel,
30 + unstable_shouldYield: () => boolean,
31 + unstable_requestPaint: () => void,
32 + unstable_now: () => DOMHighResTimeStamp,
33 +};
34 +
35 +declare var nativeRuntimeScheduler: void | NativeSchedulerType;
36 +
37 +export const unstable_UserBlockingPriority: PriorityLevel =
38 + typeof nativeRuntimeScheduler !== 'undefined'
39 + ? nativeRuntimeScheduler.unstable_UserBlockingPriority
40 + : Scheduler.unstable_UserBlockingPriority;
41 +
42 +export const unstable_NormalPriority: PriorityLevel =
43 + typeof nativeRuntimeScheduler !== 'undefined'
44 + ? nativeRuntimeScheduler.unstable_NormalPriority
45 + : Scheduler.unstable_NormalPriority;
46 +
47 +export const unstable_IdlePriority: PriorityLevel =
48 + typeof nativeRuntimeScheduler !== 'undefined'
49 + ? nativeRuntimeScheduler.unstable_IdlePriority
50 + : Scheduler.unstable_IdlePriority;
51 +
52 +export const unstable_LowPriority: PriorityLevel =
53 + typeof nativeRuntimeScheduler !== 'undefined'
54 + ? nativeRuntimeScheduler.unstable_LowPriority
55 + : Scheduler.unstable_LowPriority;
56 +
57 +export const unstable_ImmediatePriority: PriorityLevel =
58 + typeof nativeRuntimeScheduler !== 'undefined'
59 + ? nativeRuntimeScheduler.unstable_ImmediatePriority
60 + : Scheduler.unstable_ImmediatePriority;
61 +
62 +export const unstable_scheduleCallback: (
63 + priorityLevel: PriorityLevel,
64 + callback: Callback,
65 +) => Task =
66 + typeof nativeRuntimeScheduler !== 'undefined'
67 + ? nativeRuntimeScheduler.unstable_scheduleCallback
68 + : Scheduler.unstable_scheduleCallback;
69 +
70 +export const unstable_cancelCallback: (task: Task) => void =
71 + typeof nativeRuntimeScheduler !== 'undefined'
72 + ? nativeRuntimeScheduler.unstable_cancelCallback
73 + : Scheduler.unstable_cancelCallback;
74 +
75 +export const unstable_getCurrentPriorityLevel: () => PriorityLevel =
76 + typeof nativeRuntimeScheduler !== 'undefined'
77 + ? nativeRuntimeScheduler.unstable_getCurrentPriorityLevel
78 + : Scheduler.unstable_getCurrentPriorityLevel;
79 +
80 +export const unstable_shouldYield: () => boolean =
81 + typeof nativeRuntimeScheduler !== 'undefined'
82 + ? nativeRuntimeScheduler.unstable_shouldYield
83 + : Scheduler.unstable_shouldYield;
84 +
85 +export const unstable_requestPaint: () => void =
86 + typeof nativeRuntimeScheduler !== 'undefined'
87 + ? nativeRuntimeScheduler.unstable_requestPaint
88 + : Scheduler.unstable_requestPaint;
89 +
90 +export const unstable_now: () => number | DOMHighResTimeStamp =
91 + typeof nativeRuntimeScheduler !== 'undefined'
92 + ? nativeRuntimeScheduler.unstable_now
93 + : Scheduler.unstable_now;
94 +
95 +// These were never implemented on the native scheduler because React never calls them.
96 +// For consistency, let's disable them altogether and make them throw.
97 +export const unstable_next: any = throwNotImplemented;
98 +export const unstable_runWithPriority: any = throwNotImplemented;
99 +export const unstable_wrapCallback: any = throwNotImplemented;
100 +export const unstable_continueExecution: any = throwNotImplemented;
101 +export const unstable_pauseExecution: any = throwNotImplemented;
102 +export const unstable_getFirstCallbackNode: any = throwNotImplemented;
103 +export const unstable_forceFrameRate: any = throwNotImplemented;
104 +export const unstable_Profiling: any = null;
105 +
106 +function throwNotImplemented() {
107 + throw Error('Not implemented.');
108 +}
109 +
110 +// Flow magic to verify the exports of this file match the original version.
111 +export type {Callback, Task};
112 +((((null: any): SchedulerExportsType): SchedulerNativeExportsType): SchedulerExportsType);
scripts/rollup/bundles.js
+11
@@ -935,6 +935,17 @@ const bundles = [
935 externals: ['ReactNativeInternalFeatureFlags'],
936 },
937
938 + /******* React Scheduler Native *******/
939 + {
940 + bundleTypes: [NODE_DEV, NODE_PROD],
941 + moduleType: ISOMORPHIC,
942 + entry: 'scheduler/index.native',
943 + global: 'SchedulerNative',
944 + minifyWithProdErrorCodes: false,
945 + wrapWithModuleBoundaries: false,
946 + externals: ['ReactNativeInternalFeatureFlags'],
947 + },
948 +
949 /******* React Scheduler Post Task (experimental) *******/
950 {
951 bundleTypes: [
scripts/rollup/validate/eslintrc.cjs.js
+3
@@ -52,6 +52,9 @@ module.exports = {
52
53 // act
54 IS_REACT_ACT_ENVIRONMENT: 'readonly',
55 +
56 + // Native Scheduler
57 + nativeRuntimeScheduler: 'readonly',
58 },
59 parserOptions: {
60 ecmaVersion: 2020,