Skip to content

Commit 5bad9b0

Browse files
committed
Add feature flag to use microtasks in the React Native Fabric renderer (#27364)
## Summary This is part of an effort to align the event loop in React Native with its behavior on the Web. In this case, we're going to test enabling microtasks in React Native (Fabric) and we need React to schedule work using microtasks if available there. This just adds a feature flag to configure that behavior at runtime. ## How did you test this change? * Reviewed the generated code, which looks ok. * Did a manual sync of this PR to Meta's internal infra and tested it with my changes to enable microtasks in RN/Hermes. DiffTrain build for commit 54baa79.
1 parent 6f57bac commit 5bad9b0

File tree

11 files changed

+104
-50
lines changed

11 files changed

+104
-50
lines changed

compiled-rn/facebook-fbsource/xplat/js/RKJSModules/vendor/react-test-renderer/cjs/ReactTestRenderer-dev.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
* @noflow
88
* @nolint
99
* @preventMunge
10-
* @generated SignedSource<<3cf0c7070b82c229b406663b7dbae937>>
10+
* @generated SignedSource<<d08221cdf198c30256d8574839ecbf7a>>
1111
*/
1212

1313
'use strict';
@@ -145,7 +145,7 @@ var createRootStrictEffectsByDefault = false;
145145
var enableLazyContextPropagation = false;
146146
var enableLegacyHidden = false;
147147
var enableAsyncActions = false;
148-
var alwaysThrottleRetries = true; // Flow magic to verify the exports of this file match the original version.
148+
var alwaysThrottleRetries = true;
149149

150150
var FunctionComponent = 0;
151151
var ClassComponent = 1;
@@ -23997,7 +23997,7 @@ function createFiberRoot(
2399723997
return root;
2399823998
}
2399923999

24000-
var ReactVersion = "18.3.0-canary-a6ed60a8e-20230929";
24000+
var ReactVersion = "18.3.0-canary-54baa7997-20231002";
2400124001

2400224002
// Might add PROFILE later.
2400324003

compiled-rn/facebook-fbsource/xplat/js/RKJSModules/vendor/react-test-renderer/cjs/ReactTestRenderer-prod.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8623,7 +8623,7 @@ var devToolsConfig$jscomp$inline_1030 = {
86238623
throw Error("TestRenderer does not support findFiberByHostInstance()");
86248624
},
86258625
bundleType: 0,
8626-
version: "18.3.0-canary-a6ed60a8e-20230929",
8626+
version: "18.3.0-canary-54baa7997-20231002",
86278627
rendererPackageName: "react-test-renderer"
86288628
};
86298629
var internals$jscomp$inline_1229 = {
@@ -8654,7 +8654,7 @@ var internals$jscomp$inline_1229 = {
86548654
scheduleRoot: null,
86558655
setRefreshHandler: null,
86568656
getCurrentFiber: null,
8657-
reconcilerVersion: "18.3.0-canary-a6ed60a8e-20230929"
8657+
reconcilerVersion: "18.3.0-canary-54baa7997-20231002"
86588658
};
86598659
if ("undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__) {
86608660
var hook$jscomp$inline_1230 = __REACT_DEVTOOLS_GLOBAL_HOOK__;

compiled-rn/facebook-fbsource/xplat/js/RKJSModules/vendor/react-test-renderer/cjs/ReactTestRenderer-profiling.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9049,7 +9049,7 @@ var devToolsConfig$jscomp$inline_1072 = {
90499049
throw Error("TestRenderer does not support findFiberByHostInstance()");
90509050
},
90519051
bundleType: 0,
9052-
version: "18.3.0-canary-a6ed60a8e-20230929",
9052+
version: "18.3.0-canary-54baa7997-20231002",
90539053
rendererPackageName: "react-test-renderer"
90549054
};
90559055
var internals$jscomp$inline_1270 = {
@@ -9080,7 +9080,7 @@ var internals$jscomp$inline_1270 = {
90809080
scheduleRoot: null,
90819081
setRefreshHandler: null,
90829082
getCurrentFiber: null,
9083-
reconcilerVersion: "18.3.0-canary-a6ed60a8e-20230929"
9083+
reconcilerVersion: "18.3.0-canary-54baa7997-20231002"
90849084
};
90859085
if ("undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__) {
90869086
var hook$jscomp$inline_1271 = __REACT_DEVTOOLS_GLOBAL_HOOK__;

compiled-rn/facebook-fbsource/xplat/js/RKJSModules/vendor/react/cjs/React-dev.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ if (
2727
}
2828
"use strict";
2929

30-
var ReactVersion = "18.3.0-canary-a6ed60a8e-20230929";
30+
var ReactVersion = "18.3.0-canary-54baa7997-20231002";
3131

3232
// ATTENTION
3333
// When adding new symbols to this file,

compiled-rn/facebook-fbsource/xplat/js/RKJSModules/vendor/react/cjs/React-prod.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -616,4 +616,4 @@ exports.useSyncExternalStore = function (
616616
exports.useTransition = function () {
617617
return ReactCurrentDispatcher.current.useTransition();
618618
};
619-
exports.version = "18.3.0-canary-a6ed60a8e-20230929";
619+
exports.version = "18.3.0-canary-54baa7997-20231002";

compiled-rn/facebook-fbsource/xplat/js/RKJSModules/vendor/react/cjs/React-profiling.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -619,7 +619,7 @@ exports.useSyncExternalStore = function (
619619
exports.useTransition = function () {
620620
return ReactCurrentDispatcher.current.useTransition();
621621
};
622-
exports.version = "18.3.0-canary-a6ed60a8e-20230929";
622+
exports.version = "18.3.0-canary-54baa7997-20231002";
623623

624624
/* global __REACT_DEVTOOLS_GLOBAL_HOOK__ */
625625
if (
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
a6ed60a8eb0626e5f84d0bdbb62c0b61219150d3
1+
54baa7997c7b0bbd456460ead6e051655ea43790

compiled-rn/facebook-fbsource/xplat/js/react-native-github/Libraries/Renderer/implementations/ReactFabric-dev.fb.js

Lines changed: 33 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
* @noflow
88
* @nolint
99
* @preventMunge
10-
* @generated SignedSource<<86fb5a18e030273bb12b79024c6073c2>>
10+
* @generated SignedSource<<c7798d7e49297e588bffdcccc6aa6cb9>>
1111
*/
1212

1313
'use strict';
@@ -3178,7 +3178,9 @@ function dispatchEvent(target, topLevelType, nativeEvent) {
31783178
var enableUseRefAccessWarning = dynamicFlags.enableUseRefAccessWarning,
31793179
enableDeferRootSchedulingToMicrotask =
31803180
dynamicFlags.enableDeferRootSchedulingToMicrotask,
3181-
alwaysThrottleRetries = dynamicFlags.alwaysThrottleRetries; // The rest of the flags are static for better dead code elimination.
3181+
alwaysThrottleRetries = dynamicFlags.alwaysThrottleRetries,
3182+
useMicrotasksForSchedulingInFabric =
3183+
dynamicFlags.useMicrotasksForSchedulingInFabric; // The rest of the flags are static for better dead code elimination.
31823184
var enableSchedulingProfiler = true;
31833185
var enableProfilerTimer = true;
31843186
var enableProfilerCommitHooks = true;
@@ -5073,6 +5075,12 @@ function preloadInstance(type, props) {
50735075
function waitForCommitToBeReady() {
50745076
return null;
50755077
}
5078+
// Microtasks
5079+
// -------------------
5080+
5081+
var supportsMicrotasks = useMicrotasksForSchedulingInFabric;
5082+
var scheduleMicrotask =
5083+
typeof queueMicrotask === "function" ? queueMicrotask : scheduleTimeout;
50765084

50775085
// This is ok in DOM because they types are interchangeable, but in React Native
50785086
// they aren't.
@@ -10097,7 +10105,28 @@ function scheduleImmediateTask(cb) {
1009710105
} // TODO: Can we land supportsMicrotasks? Which environments don't support it?
1009810106
// Alternatively, can we move this check to the host config?
1009910107

10100-
{
10108+
if (supportsMicrotasks) {
10109+
scheduleMicrotask(function () {
10110+
// In Safari, appending an iframe forces microtasks to run.
10111+
// https://github.com/facebook/react/issues/22459
10112+
// We don't support running callbacks in the middle of render
10113+
// or commit so we need to check against that.
10114+
var executionContext = getExecutionContext();
10115+
10116+
if ((executionContext & (RenderContext | CommitContext)) !== NoContext) {
10117+
// Note that this would still prematurely flush the callbacks
10118+
// if this happens outside render or commit phase (e.g. in an event).
10119+
// Intentionally using a macrotask instead of a microtask here. This is
10120+
// wrong semantically but it prevents an infinite loop. The bug is
10121+
// Safari's, not ours, so we just do our best to not crash even though
10122+
// the behavior isn't completely correct.
10123+
scheduleCallback$2(ImmediatePriority, cb);
10124+
return;
10125+
}
10126+
10127+
cb();
10128+
});
10129+
} else {
1010110130
// If microtasks are not supported, use Scheduler.
1010210131
scheduleCallback$2(ImmediatePriority, cb);
1010310132
}
@@ -27034,7 +27063,7 @@ function createFiberRoot(
2703427063
return root;
2703527064
}
2703627065

27037-
var ReactVersion = "18.3.0-canary-84876954";
27066+
var ReactVersion = "18.3.0-canary-4227b2ef";
2703827067

2703927068
function createPortal$1(
2704027069
children,

compiled-rn/facebook-fbsource/xplat/js/react-native-github/Libraries/Renderer/implementations/ReactFabric-prod.fb.js

Lines changed: 32 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -7,14 +7,14 @@
77
* @noflow
88
* @nolint
99
* @preventMunge
10-
* @generated SignedSource<<c369fd4070037f1dc7d616d80d10dcfd>>
10+
* @generated SignedSource<<35a02eea4da4b468c9397d48533b560b>>
1111
*/
1212

1313
"use strict";
1414
require("react-native/Libraries/ReactPrivate/ReactNativePrivateInitializeCore");
1515
var ReactNativePrivateInterface = require("react-native/Libraries/ReactPrivate/ReactNativePrivateInterface"),
16-
React = require("react"),
1716
dynamicFlags = require("ReactNativeInternalFeatureFlags"),
17+
React = require("react"),
1818
Scheduler = require("scheduler");
1919
function invokeGuardedCallbackImpl(name, func, context) {
2020
var funcArgs = Array.prototype.slice.call(arguments, 3);
@@ -1318,6 +1318,8 @@ var enableUseRefAccessWarning = dynamicFlags.enableUseRefAccessWarning,
13181318
enableDeferRootSchedulingToMicrotask =
13191319
dynamicFlags.enableDeferRootSchedulingToMicrotask,
13201320
alwaysThrottleRetries = dynamicFlags.alwaysThrottleRetries,
1321+
useMicrotasksForSchedulingInFabric =
1322+
dynamicFlags.useMicrotasksForSchedulingInFabric,
13211323
scheduleCallback$2 = Scheduler.unstable_scheduleCallback,
13221324
cancelCallback$1 = Scheduler.unstable_cancelCallback,
13231325
shouldYield = Scheduler.unstable_shouldYield,
@@ -1627,6 +1629,8 @@ function cloneHiddenInstance(instance) {
16271629
canonical: instance.canonical
16281630
};
16291631
}
1632+
var scheduleMicrotask =
1633+
"function" === typeof queueMicrotask ? queueMicrotask : scheduleTimeout;
16301634
function getInstanceFromNode(node) {
16311635
return null != node.canonical && null != node.canonical.internalInstanceHandle
16321636
? node.canonical.internalInstanceHandle
@@ -3361,7 +3365,7 @@ function ensureRootIsScheduled(root) {
33613365
mightHavePendingSyncWork = !0;
33623366
didScheduleMicrotask ||
33633367
((didScheduleMicrotask = !0),
3364-
scheduleCallback$2(ImmediatePriority, processRootScheduleInMicrotask));
3368+
scheduleImmediateTask(processRootScheduleInMicrotask));
33653369
enableDeferRootSchedulingToMicrotask ||
33663370
scheduleTaskForRootDuringMicrotask(root, now());
33673371
}
@@ -3446,8 +3450,7 @@ function flushSyncWorkAcrossRoots_impl(onlyLegacy) {
34463450
if ("function" === typeof AggregateError)
34473451
throw new AggregateError(errors);
34483452
for (onlyLegacy = 1; onlyLegacy < errors.length; onlyLegacy++)
3449-
(didPerformSomeWork = throwError.bind(null, errors[onlyLegacy])),
3450-
scheduleCallback$2(ImmediatePriority, didPerformSomeWork);
3453+
scheduleImmediateTask(throwError.bind(null, errors[onlyLegacy]));
34513454
}
34523455
throw errors[0];
34533456
}
@@ -3547,6 +3550,15 @@ function scheduleTaskForRootDuringMicrotask(root, currentTime) {
35473550
root.callbackNode = suspendedLanes;
35483551
return currentTime;
35493552
}
3553+
function scheduleImmediateTask(cb) {
3554+
useMicrotasksForSchedulingInFabric
3555+
? scheduleMicrotask(function () {
3556+
0 !== (executionContext & 6)
3557+
? scheduleCallback$2(ImmediatePriority, cb)
3558+
: cb();
3559+
})
3560+
: scheduleCallback$2(ImmediatePriority, cb);
3561+
}
35503562
var ReactCurrentDispatcher$1 = ReactSharedInternals.ReactCurrentDispatcher,
35513563
ReactCurrentBatchConfig$2 = ReactSharedInternals.ReactCurrentBatchConfig,
35523564
renderLanes$1 = 0,
@@ -9425,10 +9437,10 @@ batchedUpdatesImpl = function (fn, a) {
94259437
}
94269438
};
94279439
var roots = new Map(),
9428-
devToolsConfig$jscomp$inline_1039 = {
9440+
devToolsConfig$jscomp$inline_1035 = {
94299441
findFiberByHostInstance: getInstanceFromNode,
94309442
bundleType: 0,
9431-
version: "18.3.0-canary-0ca674fe",
9443+
version: "18.3.0-canary-6367a5b9",
94329444
rendererPackageName: "react-native-renderer",
94339445
rendererConfig: {
94349446
getInspectorDataForInstance: getInspectorDataForInstance,
@@ -9444,11 +9456,11 @@ var roots = new Map(),
94449456
}.bind(null, findNodeHandle)
94459457
}
94469458
};
9447-
var internals$jscomp$inline_1281 = {
9448-
bundleType: devToolsConfig$jscomp$inline_1039.bundleType,
9449-
version: devToolsConfig$jscomp$inline_1039.version,
9450-
rendererPackageName: devToolsConfig$jscomp$inline_1039.rendererPackageName,
9451-
rendererConfig: devToolsConfig$jscomp$inline_1039.rendererConfig,
9459+
var internals$jscomp$inline_1277 = {
9460+
bundleType: devToolsConfig$jscomp$inline_1035.bundleType,
9461+
version: devToolsConfig$jscomp$inline_1035.version,
9462+
rendererPackageName: devToolsConfig$jscomp$inline_1035.rendererPackageName,
9463+
rendererConfig: devToolsConfig$jscomp$inline_1035.rendererConfig,
94529464
overrideHookState: null,
94539465
overrideHookStateDeletePath: null,
94549466
overrideHookStateRenamePath: null,
@@ -9464,26 +9476,26 @@ var internals$jscomp$inline_1281 = {
94649476
return null === fiber ? null : fiber.stateNode;
94659477
},
94669478
findFiberByHostInstance:
9467-
devToolsConfig$jscomp$inline_1039.findFiberByHostInstance ||
9479+
devToolsConfig$jscomp$inline_1035.findFiberByHostInstance ||
94689480
emptyFindFiberByHostInstance,
94699481
findHostInstancesForRefresh: null,
94709482
scheduleRefresh: null,
94719483
scheduleRoot: null,
94729484
setRefreshHandler: null,
94739485
getCurrentFiber: null,
9474-
reconcilerVersion: "18.3.0-canary-0ca674fe"
9486+
reconcilerVersion: "18.3.0-canary-6367a5b9"
94759487
};
94769488
if ("undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__) {
9477-
var hook$jscomp$inline_1282 = __REACT_DEVTOOLS_GLOBAL_HOOK__;
9489+
var hook$jscomp$inline_1278 = __REACT_DEVTOOLS_GLOBAL_HOOK__;
94789490
if (
9479-
!hook$jscomp$inline_1282.isDisabled &&
9480-
hook$jscomp$inline_1282.supportsFiber
9491+
!hook$jscomp$inline_1278.isDisabled &&
9492+
hook$jscomp$inline_1278.supportsFiber
94819493
)
94829494
try {
9483-
(rendererID = hook$jscomp$inline_1282.inject(
9484-
internals$jscomp$inline_1281
9495+
(rendererID = hook$jscomp$inline_1278.inject(
9496+
internals$jscomp$inline_1277
94859497
)),
9486-
(injectedHook = hook$jscomp$inline_1282);
9498+
(injectedHook = hook$jscomp$inline_1278);
94879499
} catch (err) {}
94889500
}
94899501
exports.createPortal = function (children, containerTag) {

0 commit comments

Comments
 (0)