Partially restore feature flag to disable event loop on bridgeless (#48892)

Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/48892

Changelog: [internal]

Reviewed By: javache, Abbondanzo

Differential Revision: D68557746

fbshipit-source-id: d94877d03dc6ea2bf6bca45da77a0a769fa0efeb
This commit is contained in:
Rubén Norte
2025-01-23 08:12:35 -08:00
committed by Facebook GitHub Bot
parent 317f130267
commit 8a2b44568d
6 changed files with 97 additions and 51 deletions
+68 -47
View File
@@ -10,6 +10,9 @@
'use strict';
const ReactNativeFeatureFlags = require('../../src/private/featureflags/ReactNativeFeatureFlags');
const NativeReactNativeFeatureFlags =
require('../../src/private/featureflags/specs/NativeReactNativeFeatureFlags').default;
const {polyfillGlobal} = require('../Utilities/PolyfillFunctions');
if (__DEV__) {
@@ -18,46 +21,19 @@ if (__DEV__) {
}
}
const isEventLoopEnabled = (() => {
if (NativeReactNativeFeatureFlags == null) {
return false;
}
return (
ReactNativeFeatureFlags.enableBridgelessArchitecture() &&
!ReactNativeFeatureFlags.disableEventLoopOnBridgeless()
);
})();
// In bridgeless mode, timers are host functions installed from cpp.
if (global.RN$Bridgeless === true) {
polyfillGlobal(
'requestIdleCallback',
() =>
require('../../src/private/webapis/idlecallbacks/specs/NativeIdleCallbacks')
.default.requestIdleCallback,
);
polyfillGlobal(
'cancelIdleCallback',
() =>
require('../../src/private/webapis/idlecallbacks/specs/NativeIdleCallbacks')
.default.cancelIdleCallback,
);
// This is the flag that tells React to use `queueMicrotask` to batch state
// updates, instead of using the scheduler to schedule a regular task.
// We use a global variable because we don't currently have any other
// mechanism to pass feature flags from RN to React in OSS.
global.RN$enableMicrotasksInReact = true;
polyfillGlobal(
'queueMicrotask',
() =>
require('../../src/private/webapis/microtasks/specs/NativeMicrotasks')
.default.queueMicrotask,
);
// We shim the immediate APIs via `queueMicrotask` to maintain the backward
// compatibility.
polyfillGlobal(
'setImmediate',
() => require('./Timers/immediateShim').setImmediate,
);
polyfillGlobal(
'clearImmediate',
() => require('./Timers/immediateShim').clearImmediate,
);
} else {
if (global.RN$Bridgeless !== true) {
/**
* Set up timers.
* You can use this module directly, or just require InitializeCore.
@@ -83,7 +59,50 @@ if (global.RN$Bridgeless === true) {
defineLazyTimer('cancelAnimationFrame');
defineLazyTimer('requestIdleCallback');
defineLazyTimer('cancelIdleCallback');
} else if (isEventLoopEnabled) {
polyfillGlobal(
'requestIdleCallback',
() =>
require('../../src/private/webapis/idlecallbacks/specs/NativeIdleCallbacks')
.default.requestIdleCallback,
);
polyfillGlobal(
'cancelIdleCallback',
() =>
require('../../src/private/webapis/idlecallbacks/specs/NativeIdleCallbacks')
.default.cancelIdleCallback,
);
}
// We need to check if the native module is available before accessing the
// feature flag, because otherwise the API would throw an error in the legacy
// architecture in OSS, where the native module isn't available.
if (isEventLoopEnabled) {
// This is the flag that tells React to use `queueMicrotask` to batch state
// updates, instead of using the scheduler to schedule a regular task.
// We use a global variable because we don't currently have any other
// mechanism to pass feature flags from RN to React in OSS.
global.RN$enableMicrotasksInReact = true;
polyfillGlobal(
'queueMicrotask',
() =>
require('../../src/private/webapis/microtasks/specs/NativeMicrotasks')
.default.queueMicrotask,
);
// We shim the immediate APIs via `queueMicrotask` to maintain the backward
// compatibility.
polyfillGlobal(
'setImmediate',
() => require('./Timers/immediateShim').setImmediate,
);
polyfillGlobal(
'clearImmediate',
() => require('./Timers/immediateShim').clearImmediate,
);
} else {
// Polyfill it with promise (regardless it's polyfilled or native) otherwise.
polyfillGlobal(
'queueMicrotask',
@@ -93,12 +112,14 @@ if (global.RN$Bridgeless === true) {
// When promise was polyfilled hence is queued to the RN microtask queue,
// we polyfill the immediate APIs as aliases to the ReactNativeMicrotask APIs.
// Note that in bridgeless mode, immediate APIs are installed from cpp.
polyfillGlobal(
'setImmediate',
() => require('./Timers/JSTimers').queueReactNativeMicrotask,
);
polyfillGlobal(
'clearImmediate',
() => require('./Timers/JSTimers').clearReactNativeMicrotask,
);
if (global.RN$Bridgeless !== true) {
polyfillGlobal(
'setImmediate',
() => require('./Timers/JSTimers').queueReactNativeMicrotask,
);
polyfillGlobal(
'clearImmediate',
() => require('./Timers/JSTimers').clearReactNativeMicrotask,
);
}
}
@@ -4,7 +4,7 @@
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @generated SignedSource<<9e4ac7a270dd74f6978374d8e2c05013>>
* @generated SignedSource<<70ce0689b8452f99877fa46b9f6b6215>>
*/
/**
@@ -54,6 +54,13 @@ bool NativeReactNativeFeatureFlags::completeReactInstanceCreationOnBgThreadOnAnd
return ReactNativeFeatureFlags::completeReactInstanceCreationOnBgThreadOnAndroid();
}
bool NativeReactNativeFeatureFlags::disableEventLoopOnBridgeless(
jsi::Runtime& /*runtime*/) {
// This flag is configured with `skipNativeAPI: true`.
// TODO(T204838867): Implement support for optional methods in C++ TM codegen and remove the method definition altogether.
return false;
}
bool NativeReactNativeFeatureFlags::disableMountItemReorderingAndroid(
jsi::Runtime& /*runtime*/) {
return ReactNativeFeatureFlags::disableMountItemReorderingAndroid();
@@ -4,7 +4,7 @@
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @generated SignedSource<<c11c50b272b571325ee3947ec53f0050>>
* @generated SignedSource<<3aadd0d890f3dac9fee5bc465d759203>>
*/
/**
@@ -41,6 +41,8 @@ class NativeReactNativeFeatureFlags
bool completeReactInstanceCreationOnBgThreadOnAndroid(jsi::Runtime& runtime);
bool disableEventLoopOnBridgeless(jsi::Runtime& runtime);
bool disableMountItemReorderingAndroid(jsi::Runtime& runtime);
bool enableAccumulatedUpdatesInRawPropsAndroid(jsi::Runtime& runtime);
@@ -66,6 +66,16 @@ const definitions: FeatureFlagDefinitions = {
purpose: 'release',
},
},
disableEventLoopOnBridgeless: {
defaultValue: false,
metadata: {
description:
'The bridgeless architecture enables the event loop by default. This feature flag allows us to force disabling it in specific instances.',
expectedReleaseValue: true,
purpose: 'release',
},
skipNativeAPI: true,
},
disableMountItemReorderingAndroid: {
defaultValue: false,
metadata: {
@@ -4,7 +4,7 @@
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @generated SignedSource<<811a054f0ada56d8cc1ed21c6930fc52>>
* @generated SignedSource<<43c428552b2f180bccddcfe62fc36697>>
* @flow strict
*/
@@ -49,6 +49,7 @@ export type ReactNativeFeatureFlags = $ReadOnly<{
commonTestFlag: Getter<boolean>,
commonTestFlagWithoutNativeImplementation: Getter<boolean>,
completeReactInstanceCreationOnBgThreadOnAndroid: Getter<boolean>,
disableEventLoopOnBridgeless: Getter<boolean>,
disableMountItemReorderingAndroid: Getter<boolean>,
enableAccumulatedUpdatesInRawPropsAndroid: Getter<boolean>,
enableBridgelessArchitecture: Getter<boolean>,
@@ -172,6 +173,10 @@ export const commonTestFlagWithoutNativeImplementation: Getter<boolean> = create
* Do not wait for a main-thread dispatch to complete init to start executing work on the JS thread on Android
*/
export const completeReactInstanceCreationOnBgThreadOnAndroid: Getter<boolean> = createNativeFlagGetter('completeReactInstanceCreationOnBgThreadOnAndroid', true);
/**
* The bridgeless architecture enables the event loop by default. This feature flag allows us to force disabling it in specific instances.
*/
export const disableEventLoopOnBridgeless: Getter<boolean> = createNativeFlagGetter('disableEventLoopOnBridgeless', false);
/**
* Prevent FabricMountingManager from reordering mountitems, which may lead to invalid state on the UI thread
*/
@@ -4,7 +4,7 @@
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @generated SignedSource<<bcb501bc8f71f02c82a58b898e73d9a0>>
* @generated SignedSource<<2dbeae49bc79bdbbf06c54273b2e2b9b>>
* @flow strict
*/
@@ -26,6 +26,7 @@ export interface Spec extends TurboModule {
+commonTestFlag?: () => boolean;
+commonTestFlagWithoutNativeImplementation?: () => boolean;
+completeReactInstanceCreationOnBgThreadOnAndroid?: () => boolean;
+disableEventLoopOnBridgeless?: () => boolean;
+disableMountItemReorderingAndroid?: () => boolean;
+enableAccumulatedUpdatesInRawPropsAndroid?: () => boolean;
+enableBridgelessArchitecture?: () => boolean;