Skip to content

Commit

Permalink
Unify feature flags for event loop (2nd attempt)
Browse files Browse the repository at this point in the history
Summary:
Changelog: [internal]

This unifies all the feature flags that control the new event loop on RN. Before, we'd have granular flags for different aspects of it. With this diff, we enable the event loop by default with bridgeless, and we introduce a new flag to explicitly disable it in that case if necessary.

When we're ready to clean up this opt-out, we just need to remove the `&& !ReactNativeFeatureFlags::disableEventLoopOnBridgeless()` conditions.

Reviewed By: fkgozali

Differential Revision: D64464902
  • Loading branch information
rubennorte authored and facebook-github-bot committed Oct 17, 2024
1 parent 644f8dd commit 1c5f43b
Show file tree
Hide file tree
Showing 31 changed files with 208 additions and 514 deletions.
12 changes: 0 additions & 12 deletions packages/react-native/Libraries/AppDelegate/RCTAppDelegate.mm
Original file line number Diff line number Diff line change
Expand Up @@ -307,18 +307,6 @@ - (RCTRootViewFactory *)createRCTRootViewFactory

class RCTAppDelegateBridgelessFeatureFlags : public facebook::react::ReactNativeFeatureFlagsDefaults {
public:
bool useModernRuntimeScheduler() override
{
return true;
}
bool enableMicrotasks() override
{
return true;
}
bool batchRenderingUpdatesInEventLoop() override
{
return true;
}
bool enableBridgelessArchitecture() override
{
return true;
Expand Down
31 changes: 21 additions & 10 deletions packages/react-native/Libraries/Core/setUpTimers.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,25 @@ if (__DEV__) {
}
}

const isEventLoopEnabled = (() => {
if (NativeReactNativeFeatureFlags == null) {
return false;
}

if (NativeReactNativeFeatureFlags.disableEventLoopOnBridgeless == null) {
// Flags not unified yet
return (
ReactNativeFeatureFlags.useModernRuntimeScheduler() &&
ReactNativeFeatureFlags.enableMicrotasks()
);
} else {
return (
ReactNativeFeatureFlags.enableBridgelessArchitecture() &&
!ReactNativeFeatureFlags.disableEventLoopOnBridgeless()
);
}
})();

// In bridgeless mode, timers are host functions installed from cpp.
if (global.RN$Bridgeless !== true) {
/**
Expand Down Expand Up @@ -48,12 +67,7 @@ if (global.RN$Bridgeless !== true) {
defineLazyTimer('cancelAnimationFrame');
defineLazyTimer('requestIdleCallback');
defineLazyTimer('cancelIdleCallback');
} else if (
// TODO remove this condition when bridgeless == modern scheduler everywhere.
NativeReactNativeFeatureFlags != null &&
// eslint-disable-next-line react-hooks/rules-of-hooks -- false positive due to `use` prefix
ReactNativeFeatureFlags.useModernRuntimeScheduler()
) {
} else if (isEventLoopEnabled) {
polyfillGlobal(
'requestIdleCallback',
() =>
Expand All @@ -72,10 +86,7 @@ if (global.RN$Bridgeless !== true) {
// 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 (
NativeReactNativeFeatureFlags != null &&
ReactNativeFeatureFlags.enableMicrotasks()
) {
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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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<<7d0c7d2dac41c4a64c3c8301b3865fdd>>
* @generated SignedSource<<9735aa2b6c596980927a6899b528cad7>>
*/

/**
Expand Down Expand Up @@ -41,16 +41,16 @@ public object ReactNativeFeatureFlags {
public fun allowRecursiveCommitsWithSynchronousMountOnAndroid(): Boolean = accessor.allowRecursiveCommitsWithSynchronousMountOnAndroid()

/**
* When enabled, the RuntimeScheduler processing the event loop will batch all rendering updates and dispatch them together at the end of each iteration of the loop.
* Do not wait for a main-thread dispatch to complete init to start executing work on the JS thread on Android
*/
@JvmStatic
public fun batchRenderingUpdatesInEventLoop(): Boolean = accessor.batchRenderingUpdatesInEventLoop()
public fun completeReactInstanceCreationOnBgThreadOnAndroid(): Boolean = accessor.completeReactInstanceCreationOnBgThreadOnAndroid()

/**
* Do not wait for a main-thread dispatch to complete init to start executing work on the JS thread on Android
* The bridgeless architecture enables the event loop by default. This feature flag allows us to force disabling it in specific instances.
*/
@JvmStatic
public fun completeReactInstanceCreationOnBgThreadOnAndroid(): Boolean = accessor.completeReactInstanceCreationOnBgThreadOnAndroid()
public fun disableEventLoopOnBridgeless(): Boolean = accessor.disableEventLoopOnBridgeless()

/**
* Kill-switch to turn off support for aling-items:baseline on Fabric iOS.
Expand Down Expand Up @@ -142,12 +142,6 @@ public object ReactNativeFeatureFlags {
@JvmStatic
public fun enableLongTaskAPI(): Boolean = accessor.enableLongTaskAPI()

/**
* Enables the use of microtasks in Hermes (scheduling) and RuntimeScheduler (execution).
*/
@JvmStatic
public fun enableMicrotasks(): Boolean = accessor.enableMicrotasks()

/**
* Moves execution of pre-mount items to outside the choregrapher in the main thread, so we can estimate idle time more precisely (Android only).
*/
Expand Down Expand Up @@ -268,12 +262,6 @@ public object ReactNativeFeatureFlags {
@JvmStatic
public fun useImmediateExecutorInAndroidBridgeless(): Boolean = accessor.useImmediateExecutorInAndroidBridgeless()

/**
* When enabled, it uses the modern fork of RuntimeScheduler that allows scheduling tasks with priorities from any thread.
*/
@JvmStatic
public fun useModernRuntimeScheduler(): Boolean = accessor.useModernRuntimeScheduler()

/**
* When enabled, the native view configs are used in bridgeless mode.
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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<<cdc39ace2bf8ed5626ae6a4d1526fd6c>>
* @generated SignedSource<<dcbe660a6bb8b4dbfaf8f349b3350448>>
*/

/**
Expand All @@ -22,8 +22,8 @@ package com.facebook.react.internal.featureflags
public class ReactNativeFeatureFlagsCxxAccessor : ReactNativeFeatureFlagsAccessor {
private var commonTestFlagCache: Boolean? = null
private var allowRecursiveCommitsWithSynchronousMountOnAndroidCache: Boolean? = null
private var batchRenderingUpdatesInEventLoopCache: Boolean? = null
private var completeReactInstanceCreationOnBgThreadOnAndroidCache: Boolean? = null
private var disableEventLoopOnBridgelessCache: Boolean? = null
private var enableAlignItemsBaselineOnFabricIOSCache: Boolean? = null
private var enableAndroidLineHeightCenteringCache: Boolean? = null
private var enableBridgelessArchitectureCache: Boolean? = null
Expand All @@ -39,7 +39,6 @@ public class ReactNativeFeatureFlagsCxxAccessor : ReactNativeFeatureFlagsAccesso
private var enableLayoutAnimationsOnAndroidCache: Boolean? = null
private var enableLayoutAnimationsOnIOSCache: Boolean? = null
private var enableLongTaskAPICache: Boolean? = null
private var enableMicrotasksCache: Boolean? = null
private var enablePreciseSchedulingForPremountItemsOnAndroidCache: Boolean? = null
private var enablePropsUpdateReconciliationAndroidCache: Boolean? = null
private var enableReportEventPaintTimeCache: Boolean? = null
Expand All @@ -60,7 +59,6 @@ public class ReactNativeFeatureFlagsCxxAccessor : ReactNativeFeatureFlagsAccesso
private var traceTurboModulePromiseRejectionsOnAndroidCache: Boolean? = null
private var useFabricInteropCache: Boolean? = null
private var useImmediateExecutorInAndroidBridgelessCache: Boolean? = null
private var useModernRuntimeSchedulerCache: Boolean? = null
private var useNativeViewConfigsInBridgelessModeCache: Boolean? = null
private var useOptimisedViewPreallocationOnAndroidCache: Boolean? = null
private var useOptimizedEventBatchingOnAndroidCache: Boolean? = null
Expand All @@ -86,20 +84,20 @@ public class ReactNativeFeatureFlagsCxxAccessor : ReactNativeFeatureFlagsAccesso
return cached
}

override fun batchRenderingUpdatesInEventLoop(): Boolean {
var cached = batchRenderingUpdatesInEventLoopCache
override fun completeReactInstanceCreationOnBgThreadOnAndroid(): Boolean {
var cached = completeReactInstanceCreationOnBgThreadOnAndroidCache
if (cached == null) {
cached = ReactNativeFeatureFlagsCxxInterop.batchRenderingUpdatesInEventLoop()
batchRenderingUpdatesInEventLoopCache = cached
cached = ReactNativeFeatureFlagsCxxInterop.completeReactInstanceCreationOnBgThreadOnAndroid()
completeReactInstanceCreationOnBgThreadOnAndroidCache = cached
}
return cached
}

override fun completeReactInstanceCreationOnBgThreadOnAndroid(): Boolean {
var cached = completeReactInstanceCreationOnBgThreadOnAndroidCache
override fun disableEventLoopOnBridgeless(): Boolean {
var cached = disableEventLoopOnBridgelessCache
if (cached == null) {
cached = ReactNativeFeatureFlagsCxxInterop.completeReactInstanceCreationOnBgThreadOnAndroid()
completeReactInstanceCreationOnBgThreadOnAndroidCache = cached
cached = ReactNativeFeatureFlagsCxxInterop.disableEventLoopOnBridgeless()
disableEventLoopOnBridgelessCache = cached
}
return cached
}
Expand Down Expand Up @@ -239,15 +237,6 @@ public class ReactNativeFeatureFlagsCxxAccessor : ReactNativeFeatureFlagsAccesso
return cached
}

override fun enableMicrotasks(): Boolean {
var cached = enableMicrotasksCache
if (cached == null) {
cached = ReactNativeFeatureFlagsCxxInterop.enableMicrotasks()
enableMicrotasksCache = cached
}
return cached
}

override fun enablePreciseSchedulingForPremountItemsOnAndroid(): Boolean {
var cached = enablePreciseSchedulingForPremountItemsOnAndroidCache
if (cached == null) {
Expand Down Expand Up @@ -428,15 +417,6 @@ public class ReactNativeFeatureFlagsCxxAccessor : ReactNativeFeatureFlagsAccesso
return cached
}

override fun useModernRuntimeScheduler(): Boolean {
var cached = useModernRuntimeSchedulerCache
if (cached == null) {
cached = ReactNativeFeatureFlagsCxxInterop.useModernRuntimeScheduler()
useModernRuntimeSchedulerCache = cached
}
return cached
}

override fun useNativeViewConfigsInBridgelessMode(): Boolean {
var cached = useNativeViewConfigsInBridgelessModeCache
if (cached == null) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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<<b3c3d5419ec8999d61c562e6db8d5289>>
* @generated SignedSource<<731105cf7807fd9a3c929c92de91be90>>
*/

/**
Expand Down Expand Up @@ -32,10 +32,10 @@ public object ReactNativeFeatureFlagsCxxInterop {

@DoNotStrip @JvmStatic public external fun allowRecursiveCommitsWithSynchronousMountOnAndroid(): Boolean

@DoNotStrip @JvmStatic public external fun batchRenderingUpdatesInEventLoop(): Boolean

@DoNotStrip @JvmStatic public external fun completeReactInstanceCreationOnBgThreadOnAndroid(): Boolean

@DoNotStrip @JvmStatic public external fun disableEventLoopOnBridgeless(): Boolean

@DoNotStrip @JvmStatic public external fun enableAlignItemsBaselineOnFabricIOS(): Boolean

@DoNotStrip @JvmStatic public external fun enableAndroidLineHeightCentering(): Boolean
Expand Down Expand Up @@ -66,8 +66,6 @@ public object ReactNativeFeatureFlagsCxxInterop {

@DoNotStrip @JvmStatic public external fun enableLongTaskAPI(): Boolean

@DoNotStrip @JvmStatic public external fun enableMicrotasks(): Boolean

@DoNotStrip @JvmStatic public external fun enablePreciseSchedulingForPremountItemsOnAndroid(): Boolean

@DoNotStrip @JvmStatic public external fun enablePropsUpdateReconciliationAndroid(): Boolean
Expand Down Expand Up @@ -108,8 +106,6 @@ public object ReactNativeFeatureFlagsCxxInterop {

@DoNotStrip @JvmStatic public external fun useImmediateExecutorInAndroidBridgeless(): Boolean

@DoNotStrip @JvmStatic public external fun useModernRuntimeScheduler(): Boolean

@DoNotStrip @JvmStatic public external fun useNativeViewConfigsInBridgelessMode(): Boolean

@DoNotStrip @JvmStatic public external fun useOptimisedViewPreallocationOnAndroid(): Boolean
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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<<5613f8d9d9403d005becbbd9348882c6>>
* @generated SignedSource<<246695bd5949b60404bf5fa9d1c6a9da>>
*/

/**
Expand All @@ -27,10 +27,10 @@ public open class ReactNativeFeatureFlagsDefaults : ReactNativeFeatureFlagsProvi

override fun allowRecursiveCommitsWithSynchronousMountOnAndroid(): Boolean = false

override fun batchRenderingUpdatesInEventLoop(): Boolean = false

override fun completeReactInstanceCreationOnBgThreadOnAndroid(): Boolean = false

override fun disableEventLoopOnBridgeless(): Boolean = false

override fun enableAlignItemsBaselineOnFabricIOS(): Boolean = true

override fun enableAndroidLineHeightCentering(): Boolean = false
Expand Down Expand Up @@ -61,8 +61,6 @@ public open class ReactNativeFeatureFlagsDefaults : ReactNativeFeatureFlagsProvi

override fun enableLongTaskAPI(): Boolean = false

override fun enableMicrotasks(): Boolean = false

override fun enablePreciseSchedulingForPremountItemsOnAndroid(): Boolean = false

override fun enablePropsUpdateReconciliationAndroid(): Boolean = false
Expand Down Expand Up @@ -103,8 +101,6 @@ public open class ReactNativeFeatureFlagsDefaults : ReactNativeFeatureFlagsProvi

override fun useImmediateExecutorInAndroidBridgeless(): Boolean = false

override fun useModernRuntimeScheduler(): Boolean = false

override fun useNativeViewConfigsInBridgelessMode(): Boolean = false

override fun useOptimisedViewPreallocationOnAndroid(): Boolean = false
Expand Down
Loading

0 comments on commit 1c5f43b

Please sign in to comment.