diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/fabric/FabricUIManager.java b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/fabric/FabricUIManager.java index 6c28d95ffa6..74c0e64d188 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/fabric/FabricUIManager.java +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/fabric/FabricUIManager.java @@ -764,6 +764,14 @@ public class FabricUIManager isLayoutable)); } + @SuppressLint("NotInvokedPrivateMethod") + @SuppressWarnings("unused") + @AnyThread + @ThreadConfined(ANY) + private boolean isOnMainThread() { + return UiThreadUtil.isOnUiThread(); + } + @SuppressWarnings("unused") @AnyThread @ThreadConfined(ANY) diff --git a/packages/react-native/ReactAndroid/src/main/jni/react/fabric/Binding.cpp b/packages/react-native/ReactAndroid/src/main/jni/react/fabric/Binding.cpp index b1d443cc265..92c29f80f1a 100644 --- a/packages/react-native/ReactAndroid/src/main/jni/react/fabric/Binding.cpp +++ b/packages/react-native/ReactAndroid/src/main/jni/react/fabric/Binding.cpp @@ -513,7 +513,7 @@ void Binding::schedulerDidRequestPreliminaryViewAllocation( if (!mountingManager) { return; } - mountingManager->preallocateShadowView(shadowNode); + mountingManager->maybePreallocateShadowView(shadowNode); } void Binding::schedulerDidDispatchCommand( diff --git a/packages/react-native/ReactAndroid/src/main/jni/react/fabric/FabricMountingManager.cpp b/packages/react-native/ReactAndroid/src/main/jni/react/fabric/FabricMountingManager.cpp index 13124ea84be..0246cb74f8d 100644 --- a/packages/react-native/ReactAndroid/src/main/jni/react/fabric/FabricMountingManager.cpp +++ b/packages/react-native/ReactAndroid/src/main/jni/react/fabric/FabricMountingManager.cpp @@ -784,11 +784,16 @@ void FabricMountingManager::executeMount( env->DeleteLocalRef(intBufferArray); } -void FabricMountingManager::preallocateShadowView( +void FabricMountingManager::maybePreallocateShadowView( const ShadowNode& shadowNode) { if (!shadowNode.getTraits().check(ShadowNodeTraits::Trait::FormsView)) { return; } + static thread_local bool onMainThread = isOnMainThread(); + if (onMainThread) { + // View preallocation is not beneficial when rendering on the main thread + return; + } SystraceSection section("FabricMountingManager::preallocateShadowView"); @@ -844,6 +849,13 @@ void FabricMountingManager::preallocateShadowView( isLayoutableShadowNode); } +bool FabricMountingManager::isOnMainThread() { + static auto isOnMainThread = + JFabricUIManager::javaClassStatic()->getMethod( + "isOnMainThread"); + return isOnMainThread(javaUIManager_); +} + void FabricMountingManager::dispatchCommand( const ShadowView& shadowView, const std::string& commandName, diff --git a/packages/react-native/ReactAndroid/src/main/jni/react/fabric/FabricMountingManager.h b/packages/react-native/ReactAndroid/src/main/jni/react/fabric/FabricMountingManager.h index 03457b4440f..0a21a217348 100644 --- a/packages/react-native/ReactAndroid/src/main/jni/react/fabric/FabricMountingManager.h +++ b/packages/react-native/ReactAndroid/src/main/jni/react/fabric/FabricMountingManager.h @@ -32,7 +32,7 @@ class FabricMountingManager final { void onSurfaceStop(SurfaceId surfaceId); - void preallocateShadowView(const ShadowNode& shadowNode); + void maybePreallocateShadowView(const ShadowNode& shadowNode); void executeMount(const MountingTransaction& transaction); @@ -55,6 +55,8 @@ class FabricMountingManager final { void onAllAnimationsComplete(); private: + bool isOnMainThread(); + jni::global_ref javaUIManager_; std::recursive_mutex commitMutex_;