Implement optimized event batching on Android (#46270)

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

Changelog: [internal]

When analyzing traces, I noticed that we were using the choreographer to batch events in the native layer on Android. This approach isn't very efficient for 2 reasons:
1. The choreographer runs in specific intervals and there could be some delay between receiving the events and dispatching them from the choreographer.
2. A slow mount operation in the choreographer after receiving the event would completely block the dispatch for the whole duration of the operation. This could take as long as 100s of ms, so it can be very significant.

This is especially relevant with layout events, which are dispatched using the same mechanism as input events. In this case, there are instances where we delay rendering in JS because we're doing an expensive mount in the UI thread.

It makes sense to batch events in native so we don't do unnecessary work in JS to process them, but there's a better mechanism to do this. Instead of posting a frame callback in the choreographer, we can batch events using a new task in an Android handler running on the UI thread. This would run immediately after the job where the events are dispatched, after all the events are dispatched.

This implements that mechanism behind a feature flag.

Reviewed By: sammy-SC

Differential Revision: D62004018

fbshipit-source-id: d8b78a75cf05d0d8c9dd867a82a776f8d293a683
This commit is contained in:
Rubén Norte
2024-08-29 20:57:25 -07:00
committed by Facebook GitHub Bot
parent 0eec866059
commit d055efd4de
20 changed files with 162 additions and 25 deletions
@@ -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<<b66656cc0c4c1556986bcb765b1a4717>>
* @generated SignedSource<<cd8b6b6fdb11377c119f6bb979560b0e>>
*/
/**
@@ -280,6 +280,12 @@ public object ReactNativeFeatureFlags {
@JvmStatic
public fun useOptimisedViewPreallocationOnAndroid(): Boolean = accessor.useOptimisedViewPreallocationOnAndroid()
/**
* Uses an optimized mechanism for event batching on Android that does not need to wait for a Choreographer frame callback.
*/
@JvmStatic
public fun useOptimizedEventBatchingOnAndroid(): Boolean = accessor.useOptimizedEventBatchingOnAndroid()
/**
* When enabled, cloning shadow nodes within react native will update the reference held by the current JS fiber tree.
*/
@@ -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<<ffc9e4785820aa65fad28f79d27a85d2>>
* @generated SignedSource<<47dbdb6ffcd04bb7b2d2d01c4c1e7ace>>
*/
/**
@@ -62,6 +62,7 @@ public class ReactNativeFeatureFlagsCxxAccessor : ReactNativeFeatureFlagsAccesso
private var useNativeViewConfigsInBridgelessModeCache: Boolean? = null
private var useNewReactImageViewBackgroundDrawingCache: Boolean? = null
private var useOptimisedViewPreallocationOnAndroidCache: Boolean? = null
private var useOptimizedEventBatchingOnAndroidCache: Boolean? = null
private var useRuntimeShadowNodeReferenceUpdateCache: Boolean? = null
private var useRuntimeShadowNodeReferenceUpdateOnLayoutCache: Boolean? = null
private var useStateAlignmentMechanismCache: Boolean? = null
@@ -445,6 +446,15 @@ public class ReactNativeFeatureFlagsCxxAccessor : ReactNativeFeatureFlagsAccesso
return cached
}
override fun useOptimizedEventBatchingOnAndroid(): Boolean {
var cached = useOptimizedEventBatchingOnAndroidCache
if (cached == null) {
cached = ReactNativeFeatureFlagsCxxInterop.useOptimizedEventBatchingOnAndroid()
useOptimizedEventBatchingOnAndroidCache = cached
}
return cached
}
override fun useRuntimeShadowNodeReferenceUpdate(): Boolean {
var cached = useRuntimeShadowNodeReferenceUpdateCache
if (cached == null) {
@@ -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<<580db8acae42a65aeb678d2d6ef4630c>>
* @generated SignedSource<<93ce8e0026e125192af1ad86730941c0>>
*/
/**
@@ -112,6 +112,8 @@ public object ReactNativeFeatureFlagsCxxInterop {
@DoNotStrip @JvmStatic public external fun useOptimisedViewPreallocationOnAndroid(): Boolean
@DoNotStrip @JvmStatic public external fun useOptimizedEventBatchingOnAndroid(): Boolean
@DoNotStrip @JvmStatic public external fun useRuntimeShadowNodeReferenceUpdate(): Boolean
@DoNotStrip @JvmStatic public external fun useRuntimeShadowNodeReferenceUpdateOnLayout(): Boolean
@@ -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<<00aae631e9d9b146fae9be838e04e165>>
* @generated SignedSource<<be36697a6f863c364f858112767399f8>>
*/
/**
@@ -107,6 +107,8 @@ public open class ReactNativeFeatureFlagsDefaults : ReactNativeFeatureFlagsProvi
override fun useOptimisedViewPreallocationOnAndroid(): Boolean = false
override fun useOptimizedEventBatchingOnAndroid(): Boolean = false
override fun useRuntimeShadowNodeReferenceUpdate(): Boolean = false
override fun useRuntimeShadowNodeReferenceUpdateOnLayout(): Boolean = false
@@ -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<<ead344838f30d7e3f1205d7bbabbc803>>
* @generated SignedSource<<7727737ae31a239d6b68397fafadbfea>>
*/
/**
@@ -66,6 +66,7 @@ public class ReactNativeFeatureFlagsLocalAccessor : ReactNativeFeatureFlagsAcces
private var useNativeViewConfigsInBridgelessModeCache: Boolean? = null
private var useNewReactImageViewBackgroundDrawingCache: Boolean? = null
private var useOptimisedViewPreallocationOnAndroidCache: Boolean? = null
private var useOptimizedEventBatchingOnAndroidCache: Boolean? = null
private var useRuntimeShadowNodeReferenceUpdateCache: Boolean? = null
private var useRuntimeShadowNodeReferenceUpdateOnLayoutCache: Boolean? = null
private var useStateAlignmentMechanismCache: Boolean? = null
@@ -491,6 +492,16 @@ public class ReactNativeFeatureFlagsLocalAccessor : ReactNativeFeatureFlagsAcces
return cached
}
override fun useOptimizedEventBatchingOnAndroid(): Boolean {
var cached = useOptimizedEventBatchingOnAndroidCache
if (cached == null) {
cached = currentProvider.useOptimizedEventBatchingOnAndroid()
accessedFeatureFlags.add("useOptimizedEventBatchingOnAndroid")
useOptimizedEventBatchingOnAndroidCache = cached
}
return cached
}
override fun useRuntimeShadowNodeReferenceUpdate(): Boolean {
var cached = useRuntimeShadowNodeReferenceUpdateCache
if (cached == null) {
@@ -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<<2c8c28515aa6929b975ef7193c8bf72e>>
* @generated SignedSource<<d9975558a8a9981b4f43e7c5d4473231>>
*/
/**
@@ -107,6 +107,8 @@ public interface ReactNativeFeatureFlagsProvider {
@DoNotStrip public fun useOptimisedViewPreallocationOnAndroid(): Boolean
@DoNotStrip public fun useOptimizedEventBatchingOnAndroid(): Boolean
@DoNotStrip public fun useRuntimeShadowNodeReferenceUpdate(): Boolean
@DoNotStrip public fun useRuntimeShadowNodeReferenceUpdateOnLayout(): Boolean
@@ -7,6 +7,7 @@
package com.facebook.react.uimanager.events;
import android.os.Handler;
import android.view.Choreographer;
import com.facebook.infer.annotation.Nullsafe;
import com.facebook.react.bridge.LifecycleEventListener;
@@ -15,6 +16,7 @@ import com.facebook.react.bridge.ReactNoCrashSoftException;
import com.facebook.react.bridge.ReactSoftExceptionLogger;
import com.facebook.react.bridge.UIManager;
import com.facebook.react.bridge.UiThreadUtil;
import com.facebook.react.internal.featureflags.ReactNativeFeatureFlags;
import com.facebook.react.modules.core.ReactChoreographer;
import com.facebook.react.uimanager.UIManagerHelper;
import com.facebook.react.uimanager.common.UIManagerType;
@@ -27,6 +29,8 @@ import java.util.concurrent.CopyOnWriteArrayList;
*/
@Nullsafe(Nullsafe.Mode.LOCAL)
public class FabricEventDispatcher implements EventDispatcher, LifecycleEventListener {
private static final Handler uiThreadHandler = UiThreadUtil.getUiThreadHandler();
private final ReactEventEmitter mReactEventEmitter;
private final ReactApplicationContext mReactContext;
private final CopyOnWriteArrayList<EventDispatcherListener> mListeners =
@@ -36,6 +40,25 @@ public class FabricEventDispatcher implements EventDispatcher, LifecycleEventLis
private final FabricEventDispatcher.ScheduleDispatchFrameCallback mCurrentFrameCallback =
new FabricEventDispatcher.ScheduleDispatchFrameCallback();
private boolean mIsDispatchScheduled = false;
private final Runnable mDispatchEventsRunnable =
new Runnable() {
@Override
public void run() {
mIsDispatchScheduled = false;
Systrace.beginSection(
Systrace.TRACE_TAG_REACT_JAVA_BRIDGE, "BatchEventDispatchedListeners");
try {
for (BatchEventDispatchedListener listener : mPostEventDispatchListeners) {
listener.onBatchEventDispatched();
}
} finally {
Systrace.endSection(Systrace.TRACE_TAG_REACT_JAVA_BRIDGE);
}
}
};
public FabricEventDispatcher(ReactApplicationContext reactContext) {
mReactContext = reactContext;
mReactContext.addLifecycleEventListener(this);
@@ -89,7 +112,14 @@ public class FabricEventDispatcher implements EventDispatcher, LifecycleEventLis
}
private void scheduleDispatchOfBatchedEvents() {
mCurrentFrameCallback.maybeScheduleDispatchOfBatchedEvents();
if (ReactNativeFeatureFlags.useOptimizedEventBatchingOnAndroid()) {
if (!mIsDispatchScheduled) {
mIsDispatchScheduled = true;
uiThreadHandler.postAtFrontOfQueue(mDispatchEventsRunnable);
}
} else {
mCurrentFrameCallback.maybeScheduleDispatchOfBatchedEvents();
}
}
/** Add a listener to this EventDispatcher. */
@@ -137,7 +167,12 @@ public class FabricEventDispatcher implements EventDispatcher, LifecycleEventLis
private void cancelDispatchOfBatchedEvents() {
UiThreadUtil.assertOnUiThread();
mCurrentFrameCallback.stop();
if (ReactNativeFeatureFlags.useOptimizedEventBatchingOnAndroid()) {
mIsDispatchScheduled = false;
uiThreadHandler.removeCallbacks(mDispatchEventsRunnable);
} else {
mCurrentFrameCallback.stop();
}
}
public void registerEventEmitter(@UIManagerType int uiManagerType, RCTEventEmitter eventEmitter) {
@@ -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<<35f5003b77104e68e32741e4626e2ba6>>
* @generated SignedSource<<c01d216f03d56fed027117e78dc590ab>>
*/
/**
@@ -291,6 +291,12 @@ class ReactNativeFeatureFlagsProviderHolder
return method(javaProvider_);
}
bool useOptimizedEventBatchingOnAndroid() override {
static const auto method =
getReactNativeFeatureFlagsProviderJavaClass()->getMethod<jboolean()>("useOptimizedEventBatchingOnAndroid");
return method(javaProvider_);
}
bool useRuntimeShadowNodeReferenceUpdate() override {
static const auto method =
getReactNativeFeatureFlagsProviderJavaClass()->getMethod<jboolean()>("useRuntimeShadowNodeReferenceUpdate");
@@ -529,6 +535,11 @@ bool JReactNativeFeatureFlagsCxxInterop::useOptimisedViewPreallocationOnAndroid(
return ReactNativeFeatureFlags::useOptimisedViewPreallocationOnAndroid();
}
bool JReactNativeFeatureFlagsCxxInterop::useOptimizedEventBatchingOnAndroid(
facebook::jni::alias_ref<JReactNativeFeatureFlagsCxxInterop> /*unused*/) {
return ReactNativeFeatureFlags::useOptimizedEventBatchingOnAndroid();
}
bool JReactNativeFeatureFlagsCxxInterop::useRuntimeShadowNodeReferenceUpdate(
facebook::jni::alias_ref<JReactNativeFeatureFlagsCxxInterop> /*unused*/) {
return ReactNativeFeatureFlags::useRuntimeShadowNodeReferenceUpdate();
@@ -692,6 +703,9 @@ void JReactNativeFeatureFlagsCxxInterop::registerNatives() {
makeNativeMethod(
"useOptimisedViewPreallocationOnAndroid",
JReactNativeFeatureFlagsCxxInterop::useOptimisedViewPreallocationOnAndroid),
makeNativeMethod(
"useOptimizedEventBatchingOnAndroid",
JReactNativeFeatureFlagsCxxInterop::useOptimizedEventBatchingOnAndroid),
makeNativeMethod(
"useRuntimeShadowNodeReferenceUpdate",
JReactNativeFeatureFlagsCxxInterop::useRuntimeShadowNodeReferenceUpdate),
@@ -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<<a03c665dfa72c2f0514bc81d96ab827a>>
* @generated SignedSource<<0e82efb1fac0a62802f5f09e96de31d0>>
*/
/**
@@ -156,6 +156,9 @@ class JReactNativeFeatureFlagsCxxInterop
static bool useOptimisedViewPreallocationOnAndroid(
facebook::jni::alias_ref<JReactNativeFeatureFlagsCxxInterop>);
static bool useOptimizedEventBatchingOnAndroid(
facebook::jni::alias_ref<JReactNativeFeatureFlagsCxxInterop>);
static bool useRuntimeShadowNodeReferenceUpdate(
facebook::jni::alias_ref<JReactNativeFeatureFlagsCxxInterop>);
@@ -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<<c9c5d567deb97699ad0cf65594ea33ca>>
* @generated SignedSource<<31c0fac0172a6d3f9ab84a77d4967f5e>>
*/
/**
@@ -189,6 +189,10 @@ bool ReactNativeFeatureFlags::useOptimisedViewPreallocationOnAndroid() {
return getAccessor().useOptimisedViewPreallocationOnAndroid();
}
bool ReactNativeFeatureFlags::useOptimizedEventBatchingOnAndroid() {
return getAccessor().useOptimizedEventBatchingOnAndroid();
}
bool ReactNativeFeatureFlags::useRuntimeShadowNodeReferenceUpdate() {
return getAccessor().useRuntimeShadowNodeReferenceUpdate();
}
@@ -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<<748622d87b1051bbb1cd79fb479ab0e2>>
* @generated SignedSource<<56c3d93945f6c320e268c9ba32cbde0f>>
*/
/**
@@ -247,6 +247,11 @@ class ReactNativeFeatureFlags {
*/
RN_EXPORT static bool useOptimisedViewPreallocationOnAndroid();
/**
* Uses an optimized mechanism for event batching on Android that does not need to wait for a Choreographer frame callback.
*/
RN_EXPORT static bool useOptimizedEventBatchingOnAndroid();
/**
* When enabled, cloning shadow nodes within react native will update the reference held by the current JS fiber tree.
*/
@@ -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<<90f05e6a6a414704176234724ca1fc04>>
* @generated SignedSource<<73c8cf1d23aa58b4b60e4018c0ddc12e>>
*/
/**
@@ -785,6 +785,24 @@ bool ReactNativeFeatureFlagsAccessor::useOptimisedViewPreallocationOnAndroid() {
return flagValue.value();
}
bool ReactNativeFeatureFlagsAccessor::useOptimizedEventBatchingOnAndroid() {
auto flagValue = useOptimizedEventBatchingOnAndroid_.load();
if (!flagValue.has_value()) {
// This block is not exclusive but it is not necessary.
// If multiple threads try to initialize the feature flag, we would only
// be accessing the provider multiple times but the end state of this
// instance and the returned flag value would be the same.
markFlagAsAccessed(42, "useOptimizedEventBatchingOnAndroid");
flagValue = currentProvider_->useOptimizedEventBatchingOnAndroid();
useOptimizedEventBatchingOnAndroid_ = flagValue;
}
return flagValue.value();
}
bool ReactNativeFeatureFlagsAccessor::useRuntimeShadowNodeReferenceUpdate() {
auto flagValue = useRuntimeShadowNodeReferenceUpdate_.load();
@@ -794,7 +812,7 @@ bool ReactNativeFeatureFlagsAccessor::useRuntimeShadowNodeReferenceUpdate() {
// be accessing the provider multiple times but the end state of this
// instance and the returned flag value would be the same.
markFlagAsAccessed(42, "useRuntimeShadowNodeReferenceUpdate");
markFlagAsAccessed(43, "useRuntimeShadowNodeReferenceUpdate");
flagValue = currentProvider_->useRuntimeShadowNodeReferenceUpdate();
useRuntimeShadowNodeReferenceUpdate_ = flagValue;
@@ -812,7 +830,7 @@ bool ReactNativeFeatureFlagsAccessor::useRuntimeShadowNodeReferenceUpdateOnLayou
// be accessing the provider multiple times but the end state of this
// instance and the returned flag value would be the same.
markFlagAsAccessed(43, "useRuntimeShadowNodeReferenceUpdateOnLayout");
markFlagAsAccessed(44, "useRuntimeShadowNodeReferenceUpdateOnLayout");
flagValue = currentProvider_->useRuntimeShadowNodeReferenceUpdateOnLayout();
useRuntimeShadowNodeReferenceUpdateOnLayout_ = flagValue;
@@ -830,7 +848,7 @@ bool ReactNativeFeatureFlagsAccessor::useStateAlignmentMechanism() {
// be accessing the provider multiple times but the end state of this
// instance and the returned flag value would be the same.
markFlagAsAccessed(44, "useStateAlignmentMechanism");
markFlagAsAccessed(45, "useStateAlignmentMechanism");
flagValue = currentProvider_->useStateAlignmentMechanism();
useStateAlignmentMechanism_ = flagValue;
@@ -848,7 +866,7 @@ bool ReactNativeFeatureFlagsAccessor::useTurboModuleInterop() {
// be accessing the provider multiple times but the end state of this
// instance and the returned flag value would be the same.
markFlagAsAccessed(45, "useTurboModuleInterop");
markFlagAsAccessed(46, "useTurboModuleInterop");
flagValue = currentProvider_->useTurboModuleInterop();
useTurboModuleInterop_ = flagValue;
@@ -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<<e5d5840544391ffde1fe34e43bd0edc5>>
* @generated SignedSource<<94a2acd88ff16cfe528e0ec9baf6a383>>
*/
/**
@@ -73,6 +73,7 @@ class ReactNativeFeatureFlagsAccessor {
bool useNativeViewConfigsInBridgelessMode();
bool useNewReactImageViewBackgroundDrawing();
bool useOptimisedViewPreallocationOnAndroid();
bool useOptimizedEventBatchingOnAndroid();
bool useRuntimeShadowNodeReferenceUpdate();
bool useRuntimeShadowNodeReferenceUpdateOnLayout();
bool useStateAlignmentMechanism();
@@ -87,7 +88,7 @@ class ReactNativeFeatureFlagsAccessor {
std::unique_ptr<ReactNativeFeatureFlagsProvider> currentProvider_;
bool wasOverridden_;
std::array<std::atomic<const char*>, 46> accessedFeatureFlags_;
std::array<std::atomic<const char*>, 47> accessedFeatureFlags_;
std::atomic<std::optional<bool>> commonTestFlag_;
std::atomic<std::optional<bool>> allowRecursiveCommitsWithSynchronousMountOnAndroid_;
@@ -131,6 +132,7 @@ class ReactNativeFeatureFlagsAccessor {
std::atomic<std::optional<bool>> useNativeViewConfigsInBridgelessMode_;
std::atomic<std::optional<bool>> useNewReactImageViewBackgroundDrawing_;
std::atomic<std::optional<bool>> useOptimisedViewPreallocationOnAndroid_;
std::atomic<std::optional<bool>> useOptimizedEventBatchingOnAndroid_;
std::atomic<std::optional<bool>> useRuntimeShadowNodeReferenceUpdate_;
std::atomic<std::optional<bool>> useRuntimeShadowNodeReferenceUpdateOnLayout_;
std::atomic<std::optional<bool>> useStateAlignmentMechanism_;
@@ -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<<d47e51a2208f40fd2073c5e0395cd7ad>>
* @generated SignedSource<<602c539c5cf438a04a1fb4b6ce05cd3a>>
*/
/**
@@ -195,6 +195,10 @@ class ReactNativeFeatureFlagsDefaults : public ReactNativeFeatureFlagsProvider {
return false;
}
bool useOptimizedEventBatchingOnAndroid() override {
return false;
}
bool useRuntimeShadowNodeReferenceUpdate() override {
return false;
}
@@ -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<<6bfd567b419f4dbb1a72470265fae271>>
* @generated SignedSource<<ea07dfe758e8d6f5eada26850dc492a0>>
*/
/**
@@ -67,6 +67,7 @@ class ReactNativeFeatureFlagsProvider {
virtual bool useNativeViewConfigsInBridgelessMode() = 0;
virtual bool useNewReactImageViewBackgroundDrawing() = 0;
virtual bool useOptimisedViewPreallocationOnAndroid() = 0;
virtual bool useOptimizedEventBatchingOnAndroid() = 0;
virtual bool useRuntimeShadowNodeReferenceUpdate() = 0;
virtual bool useRuntimeShadowNodeReferenceUpdateOnLayout() = 0;
virtual bool useStateAlignmentMechanism() = 0;
@@ -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<<903710df33dd5666f8f2ddce79f66660>>
* @generated SignedSource<<1461fc4acff2a28056df4faa4d622a16>>
*/
/**
@@ -247,6 +247,11 @@ bool NativeReactNativeFeatureFlags::useOptimisedViewPreallocationOnAndroid(
return ReactNativeFeatureFlags::useOptimisedViewPreallocationOnAndroid();
}
bool NativeReactNativeFeatureFlags::useOptimizedEventBatchingOnAndroid(
jsi::Runtime& /*runtime*/) {
return ReactNativeFeatureFlags::useOptimizedEventBatchingOnAndroid();
}
bool NativeReactNativeFeatureFlags::useRuntimeShadowNodeReferenceUpdate(
jsi::Runtime& /*runtime*/) {
return ReactNativeFeatureFlags::useRuntimeShadowNodeReferenceUpdate();
@@ -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<<6d1f1233f646704d1403f984dabbb2e4>>
* @generated SignedSource<<9f06e832566c4c1271eaf9bb5cfdf886>>
*/
/**
@@ -119,6 +119,8 @@ class NativeReactNativeFeatureFlags
bool useOptimisedViewPreallocationOnAndroid(jsi::Runtime& runtime);
bool useOptimizedEventBatchingOnAndroid(jsi::Runtime& runtime);
bool useRuntimeShadowNodeReferenceUpdate(jsi::Runtime& runtime);
bool useRuntimeShadowNodeReferenceUpdateOnLayout(jsi::Runtime& runtime);
@@ -240,6 +240,11 @@ const definitions: FeatureFlagDefinitions = {
description:
'Moves more of the work in view preallocation to the main thread to free up JS thread.',
},
useOptimizedEventBatchingOnAndroid: {
defaultValue: false,
description:
'Uses an optimized mechanism for event batching on Android that does not need to wait for a Choreographer frame callback.',
},
useRuntimeShadowNodeReferenceUpdate: {
defaultValue: false,
description:
@@ -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<<e6f75b1da7b738958530a845290f944c>>
* @generated SignedSource<<1f82c87c0c011c0bf2e76a6e46bb1d3e>>
* @flow strict-local
*/
@@ -88,6 +88,7 @@ export type ReactNativeFeatureFlags = {
useNativeViewConfigsInBridgelessMode: Getter<boolean>,
useNewReactImageViewBackgroundDrawing: Getter<boolean>,
useOptimisedViewPreallocationOnAndroid: Getter<boolean>,
useOptimizedEventBatchingOnAndroid: Getter<boolean>,
useRuntimeShadowNodeReferenceUpdate: Getter<boolean>,
useRuntimeShadowNodeReferenceUpdateOnLayout: Getter<boolean>,
useStateAlignmentMechanism: Getter<boolean>,
@@ -332,6 +333,10 @@ export const useNewReactImageViewBackgroundDrawing: Getter<boolean> = createNati
* Moves more of the work in view preallocation to the main thread to free up JS thread.
*/
export const useOptimisedViewPreallocationOnAndroid: Getter<boolean> = createNativeFlagGetter('useOptimisedViewPreallocationOnAndroid', false);
/**
* Uses an optimized mechanism for event batching on Android that does not need to wait for a Choreographer frame callback.
*/
export const useOptimizedEventBatchingOnAndroid: Getter<boolean> = createNativeFlagGetter('useOptimizedEventBatchingOnAndroid', false);
/**
* When enabled, cloning shadow nodes within react native will update the reference held by the current JS fiber tree.
*/
@@ -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<<0f11ba941f22bed8f3b43d1332dc4557>>
* @generated SignedSource<<8370ce5bfcfa27bfdaab6549ae54b6d4>>
* @flow strict-local
*/
@@ -65,6 +65,7 @@ export interface Spec extends TurboModule {
+useNativeViewConfigsInBridgelessMode?: () => boolean;
+useNewReactImageViewBackgroundDrawing?: () => boolean;
+useOptimisedViewPreallocationOnAndroid?: () => boolean;
+useOptimizedEventBatchingOnAndroid?: () => boolean;
+useRuntimeShadowNodeReferenceUpdate?: () => boolean;
+useRuntimeShadowNodeReferenceUpdateOnLayout?: () => boolean;
+useStateAlignmentMechanism?: () => boolean;