From 3b81f259d0a6ed98369b7e51529502c2871c1f1a 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 7bb59ee17f0c6..005727b5e14d4 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 784e00a9da5b7..e0f46a07822c3 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 0e88a9674dcf8..3326b3bdc74a0 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 e88628506b690..de68e6dcccdbb 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 a9e0348ebad76..f56ad6f00eb83 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 6f487a7c275e7..b8da8afffbe28 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 fc05a456821f4..0905df2955a05 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 ad8a03ae72438..f7673e51cfd0a 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 8a33eb72270a6..d8b43417dd09d 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 105e3fd806025..b51aa5b7ec188 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 a6e41c2a51e1c..e1b8b0ca72a17 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 0df7886173b19..9b9a065de410f 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 ff956ec5e746c..acdb2bacd1a31 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