From bb0944fe5bdd619be918621a9a1647204d6e7ce1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rub=C3=A9n=20Norte?= Date: Wed, 13 Mar 2024 10:00:10 +0000 Subject: [PATCH] [RN] Use microtasks in the RN renderer based on a global flag defined by RN (#28472) ## Summary We want to enable the new event loop in React Native (https://github.com/react-native-community/discussions-and-proposals/pull/744) for all users in the new architecture (determined by the use of bridgeless, not by the use of Fabric). In order to leverage that, we need to also set the flag for the React reconciler to use microtasks for scheduling (so we'll execute them at the right time in the new event loop). This migrates from the previous approach using a dynamic flag (to be used at Meta) with the check of a global set by React Native. The reason for doing this is: 1) We still need to determine this dynamically in OSS (based on Bridgeless, not on Fabric). 2) We still need the ability to configure the behavior at Meta, and for internal build system reasons we cannot access the flag that enables microtasks in [`ReactNativeFeatureFlags`](https://github.com/facebook/react-native/blob/6c28c87c4d5d8a9f5be5e02cd7d3eba5b4aaca8c/packages/react-native/src/private/featureflags/ReactNativeFeatureFlags.js#L121). ## How did you test this change? Manually synchronized the changes to React Native and ran all tests for the new architecture on it. Also tested manually. > [!NOTE] > This change depends on https://github.com/facebook/react-native/pull/43397 which has been merged already --- .eslintrc.js | 1 + .../src/ReactFiberConfigFabric.js | 11 ++++++----- packages/shared/ReactFeatureFlags.js | 2 -- .../forks/ReactFeatureFlags.native-fb-dynamic.js | 1 - packages/shared/forks/ReactFeatureFlags.native-fb.js | 1 - packages/shared/forks/ReactFeatureFlags.native-oss.js | 1 - .../shared/forks/ReactFeatureFlags.test-renderer.js | 1 - .../forks/ReactFeatureFlags.test-renderer.native.js | 1 - .../forks/ReactFeatureFlags.test-renderer.www.js | 1 - packages/shared/forks/ReactFeatureFlags.www.js | 1 - scripts/flow/react-native-host-hooks.js | 2 ++ scripts/flow/xplat.js | 1 - scripts/rollup/validate/eslintrc.rn.js | 2 ++ 13 files changed, 11 insertions(+), 15 deletions(-) diff --git a/.eslintrc.js b/.eslintrc.js index 7bb59ee17f..005727b5e1 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -427,6 +427,7 @@ module.exports = { files: ['packages/react-native-renderer/**/*.js'], globals: { nativeFabricUIManager: 'readonly', + RN$enableMicrotasksInReact: 'readonly', }, }, { diff --git a/packages/react-native-renderer/src/ReactFiberConfigFabric.js b/packages/react-native-renderer/src/ReactFiberConfigFabric.js index 784e00a9da..e0f46a0782 100644 --- a/packages/react-native-renderer/src/ReactFiberConfigFabric.js +++ b/packages/react-native-renderer/src/ReactFiberConfigFabric.js @@ -47,10 +47,7 @@ const { unstable_getCurrentEventPriority: fabricGetCurrentEventPriority, } = nativeFabricUIManager; -import { - useMicrotasksForSchedulingInFabric, - passChildrenWhenCloningPersistedNodes, -} from 'shared/ReactFeatureFlags'; +import {passChildrenWhenCloningPersistedNodes} from 'shared/ReactFeatureFlags'; const {get: getViewConfigForType} = ReactNativeViewConfigRegistry; @@ -507,6 +504,10 @@ export const NotPendingTransition: TransitionStatus = null; // ------------------- // Microtasks // ------------------- -export const supportsMicrotasks = useMicrotasksForSchedulingInFabric; + +export const supportsMicrotasks: boolean = + typeof RN$enableMicrotasksInReact !== 'undefined' && + !!RN$enableMicrotasksInReact; + export const scheduleMicrotask: any = typeof queueMicrotask === 'function' ? queueMicrotask : scheduleTimeout; diff --git a/packages/shared/ReactFeatureFlags.js b/packages/shared/ReactFeatureFlags.js index 0e88a9674d..3326b3bdc7 100644 --- a/packages/shared/ReactFeatureFlags.js +++ b/packages/shared/ReactFeatureFlags.js @@ -115,8 +115,6 @@ export const enableFizzExternalRuntime = true; export const alwaysThrottleRetries = true; -export const useMicrotasksForSchedulingInFabric = false; - export const passChildrenWhenCloningPersistedNodes = false; export const enableUseDeferredValueInitialArg = __EXPERIMENTAL__; diff --git a/packages/shared/forks/ReactFeatureFlags.native-fb-dynamic.js b/packages/shared/forks/ReactFeatureFlags.native-fb-dynamic.js index e88628506b..de68e6dccc 100644 --- a/packages/shared/forks/ReactFeatureFlags.native-fb-dynamic.js +++ b/packages/shared/forks/ReactFeatureFlags.native-fb-dynamic.js @@ -30,7 +30,6 @@ export const enableRenderableContext = __VARIANT__; export const enableUnifiedSyncLane = __VARIANT__; export const enableUseRefAccessWarning = __VARIANT__; export const passChildrenWhenCloningPersistedNodes = __VARIANT__; -export const useMicrotasksForSchedulingInFabric = __VARIANT__; export const useModernStrictMode = __VARIANT__; // Flow magic to verify the exports of this file match the original version. diff --git a/packages/shared/forks/ReactFeatureFlags.native-fb.js b/packages/shared/forks/ReactFeatureFlags.native-fb.js index a9e0348eba..f56ad6f00e 100644 --- a/packages/shared/forks/ReactFeatureFlags.native-fb.js +++ b/packages/shared/forks/ReactFeatureFlags.native-fb.js @@ -28,7 +28,6 @@ export const { enableUnifiedSyncLane, enableUseRefAccessWarning, passChildrenWhenCloningPersistedNodes, - useMicrotasksForSchedulingInFabric, useModernStrictMode, } = dynamicFlags; diff --git a/packages/shared/forks/ReactFeatureFlags.native-oss.js b/packages/shared/forks/ReactFeatureFlags.native-oss.js index 6f487a7c27..b8da8afffb 100644 --- a/packages/shared/forks/ReactFeatureFlags.native-oss.js +++ b/packages/shared/forks/ReactFeatureFlags.native-oss.js @@ -80,7 +80,6 @@ export const enableAsyncActions = false; export const alwaysThrottleRetries = false; -export const useMicrotasksForSchedulingInFabric = false; export const passChildrenWhenCloningPersistedNodes = false; export const enableUseDeferredValueInitialArg = __EXPERIMENTAL__; export const disableClientCache = true; diff --git a/packages/shared/forks/ReactFeatureFlags.test-renderer.js b/packages/shared/forks/ReactFeatureFlags.test-renderer.js index fc05a45682..0905df2955 100644 --- a/packages/shared/forks/ReactFeatureFlags.test-renderer.js +++ b/packages/shared/forks/ReactFeatureFlags.test-renderer.js @@ -78,7 +78,6 @@ export const enableAsyncActions = true; export const alwaysThrottleRetries = true; -export const useMicrotasksForSchedulingInFabric = false; export const passChildrenWhenCloningPersistedNodes = false; export const enableUseDeferredValueInitialArg = __EXPERIMENTAL__; export const disableClientCache = true; diff --git a/packages/shared/forks/ReactFeatureFlags.test-renderer.native.js b/packages/shared/forks/ReactFeatureFlags.test-renderer.native.js index ad8a03ae72..f7673e51cf 100644 --- a/packages/shared/forks/ReactFeatureFlags.test-renderer.native.js +++ b/packages/shared/forks/ReactFeatureFlags.test-renderer.native.js @@ -78,7 +78,6 @@ export const enableAsyncActions = true; export const alwaysThrottleRetries = true; -export const useMicrotasksForSchedulingInFabric = false; export const passChildrenWhenCloningPersistedNodes = false; export const enableUseDeferredValueInitialArg = __EXPERIMENTAL__; export const disableClientCache = true; diff --git a/packages/shared/forks/ReactFeatureFlags.test-renderer.www.js b/packages/shared/forks/ReactFeatureFlags.test-renderer.www.js index 8a33eb7227..d8b43417dd 100644 --- a/packages/shared/forks/ReactFeatureFlags.test-renderer.www.js +++ b/packages/shared/forks/ReactFeatureFlags.test-renderer.www.js @@ -79,7 +79,6 @@ export const enableAsyncActions = true; export const alwaysThrottleRetries = true; -export const useMicrotasksForSchedulingInFabric = false; export const passChildrenWhenCloningPersistedNodes = false; export const enableUseDeferredValueInitialArg = true; export const disableClientCache = true; diff --git a/packages/shared/forks/ReactFeatureFlags.www.js b/packages/shared/forks/ReactFeatureFlags.www.js index 105e3fd806..b51aa5b7ec 100644 --- a/packages/shared/forks/ReactFeatureFlags.www.js +++ b/packages/shared/forks/ReactFeatureFlags.www.js @@ -106,7 +106,6 @@ export const enableFizzExternalRuntime = true; export const forceConcurrentByDefaultForTesting = false; -export const useMicrotasksForSchedulingInFabric = false; export const passChildrenWhenCloningPersistedNodes = false; export const enableAsyncDebugInfo = false; diff --git a/scripts/flow/react-native-host-hooks.js b/scripts/flow/react-native-host-hooks.js index a6e41c2a51..e1b8b0ca72 100644 --- a/scripts/flow/react-native-host-hooks.js +++ b/scripts/flow/react-native-host-hooks.js @@ -167,6 +167,8 @@ declare module 'react-native/Libraries/ReactPrivate/ReactNativePrivateInterface' declare module 'react-native/Libraries/ReactPrivate/ReactNativePrivateInitializeCore' { } +declare const RN$enableMicrotasksInReact: boolean; + // This is needed for a short term solution. // See https://github.com/facebook/react/pull/15490 for more info declare var nativeFabricUIManager: { diff --git a/scripts/flow/xplat.js b/scripts/flow/xplat.js index 0df7886173..9b9a065de4 100644 --- a/scripts/flow/xplat.js +++ b/scripts/flow/xplat.js @@ -18,6 +18,5 @@ declare module 'ReactNativeInternalFeatureFlags' { declare export var enableUnifiedSyncLane: boolean; declare export var enableUseRefAccessWarning: boolean; declare export var passChildrenWhenCloningPersistedNodes: boolean; - declare export var useMicrotasksForSchedulingInFabric: boolean; declare export var useModernStrictMode: boolean; } diff --git a/scripts/rollup/validate/eslintrc.rn.js b/scripts/rollup/validate/eslintrc.rn.js index ff956ec5e7..acdb2bacd1 100644 --- a/scripts/rollup/validate/eslintrc.rn.js +++ b/scripts/rollup/validate/eslintrc.rn.js @@ -42,6 +42,8 @@ module.exports = { // Fabric. See https://github.com/facebook/react/pull/15490 // for more information nativeFabricUIManager: 'readonly', + // RN flag to enable microtasks + RN$enableMicrotasksInReact: 'readonly', // Trusted Types trustedTypes: 'readonly', // RN supports this