diff --git a/ReactAndroid/src/main/java/com/facebook/react/fabric/FabricUIManager.java b/ReactAndroid/src/main/java/com/facebook/react/fabric/FabricUIManager.java index 9b58679f448..cfaa9e45a10 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/fabric/FabricUIManager.java +++ b/ReactAndroid/src/main/java/com/facebook/react/fabric/FabricUIManager.java @@ -193,7 +193,7 @@ public class FabricUIManager implements UIManager, LifecycleEventListener { } @DoNotStrip - private void preallocateView(int rootTag, int reactTag, final String componentName, ReadableMap props) { + private void preallocateView(int rootTag, int reactTag, final String componentName, ReadableMap props, boolean isLayoutable) { if (UiThreadUtil.isOnUiThread()) { // There is no reason to allocate views ahead of time on the main thread. return; @@ -202,7 +202,7 @@ public class FabricUIManager implements UIManager, LifecycleEventListener { ThemedReactContext context = mReactContextForRootTag.get(rootTag); String component = sComponentNames.get(componentName); synchronized (mPreMountItemsLock) { - mPreMountItems.add(new PreAllocateViewMountItem(context, rootTag, reactTag, component, props)); + mPreMountItems.add(new PreAllocateViewMountItem(context, rootTag, reactTag, component, props, isLayoutable)); } } @@ -313,6 +313,7 @@ public class FabricUIManager implements UIManager, LifecycleEventListener { @UiThread private void dispatchMountItems() { mRunStartTime = SystemClock.uptimeMillis(); + List mountItemsToDispatch; synchronized (mMountItemsLock) { if (mMountItems.isEmpty()) { @@ -322,6 +323,21 @@ public class FabricUIManager implements UIManager, LifecycleEventListener { mMountItems = new ArrayList<>(); } + + // If there are MountItems to dispatch, we make sure all the "pre mount items" are executed + ArrayDeque mPreMountItemsToDispatch = null; + synchronized (mPreMountItemsLock) { + if (!mPreMountItems.isEmpty()) { + mPreMountItemsToDispatch = mPreMountItems; + mPreMountItems = new ArrayDeque<>(PRE_MOUNT_ITEMS_INITIAL_SIZE_ARRAY); + } + } + + while (mPreMountItemsToDispatch != null && !mPreMountItemsToDispatch.isEmpty()) { + mPreMountItemsToDispatch.pollFirst().execute(mMountingManager); + } + + Systrace.beginSection( Systrace.TRACE_TAG_REACT_JAVA_BRIDGE, "FabricUIManager::mountViews (" + mountItemsToDispatch.size() + " batches)"); diff --git a/ReactAndroid/src/main/java/com/facebook/react/fabric/jsi/jni/Binding.cpp b/ReactAndroid/src/main/java/com/facebook/react/fabric/jsi/jni/Binding.cpp index 70fde602796..41a64771cd7 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/fabric/jsi/jni/Binding.cpp +++ b/ReactAndroid/src/main/java/com/facebook/react/fabric/jsi/jni/Binding.cpp @@ -166,34 +166,6 @@ local_ref getPlatformComponentName(const ShadowView& shadowView) { return componentName; } -local_ref createCreateMountItem( - const jni::global_ref& javaUIManager, - const ShadowViewMutation& mutation, - const Tag rootTag) { - static auto createJavaInstruction = - jni::findClassStatic(UIManagerJavaDescriptor) - ->getMethod(jstring, jint, jint, jboolean, ReadableMap::javaobject)>( - "createMountItem"); - - auto newChildShadowView = mutation.newChildShadowView; - - local_ref componentName = - getPlatformComponentName(newChildShadowView); - - jboolean isVirtual = newChildShadowView.layoutMetrics == EmptyLayoutMetrics; - - local_ref props = isVirtual ? nullptr : - castReadableMap(ReadableNativeMap::newObjectCxxArgs(newChildShadowView.props->rawProps)); - - return createJavaInstruction( - javaUIManager, - componentName.get(), - rootTag, - newChildShadowView.tag, - isVirtual, - props != nullptr ? props.get() : nullptr); -} - local_ref createUpdateEventEmitterMountItem( const jni::global_ref& javaUIManager, const ShadowViewMutation& mutation) { @@ -353,11 +325,6 @@ void Binding::schedulerDidFinishTransaction( oldChildShadowView.layoutMetrics == EmptyLayoutMetrics; switch (mutation.type) { - case ShadowViewMutation::Create: { - mountItems[position++] = - createCreateMountItem(javaUIManager_, mutation, rootTag); - break; - } case ShadowViewMutation::Remove: { if (!isVirtual) { mountItems[position++] = @@ -470,16 +437,14 @@ void Binding::schedulerDidRequestPreliminaryViewAllocation( bool isLayoutableShadowNode = shadowView.layoutMetrics != EmptyLayoutMetrics; - if (isLayoutableShadowNode) { - static auto preallocateView = - jni::findClassStatic(UIManagerJavaDescriptor) - ->getMethod("preallocateView"); + static auto preallocateView = + jni::findClassStatic(UIManagerJavaDescriptor) + ->getMethod("preallocateView"); - local_ref readableMap = - castReadableMap(ReadableNativeMap::newObjectCxxArgs(shadowView.props->rawProps)); - preallocateView( - javaUIManager_, surfaceId, shadowView.tag, make_jstring(shadowView.componentName).get(), readableMap.get()); - } + local_ref readableMap = + castReadableMap(ReadableNativeMap::newObjectCxxArgs(shadowView.props->rawProps)); + preallocateView( + javaUIManager_, surfaceId, shadowView.tag, make_jstring(shadowView.componentName).get(), readableMap.get(), isLayoutableShadowNode); } void Binding::registerNatives() { diff --git a/ReactAndroid/src/main/java/com/facebook/react/fabric/mounting/MountingManager.java b/ReactAndroid/src/main/java/com/facebook/react/fabric/mounting/MountingManager.java index 2ffaa4d8d01..c79c7b2d0f6 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/fabric/mounting/MountingManager.java +++ b/ReactAndroid/src/main/java/com/facebook/react/fabric/mounting/MountingManager.java @@ -168,15 +168,11 @@ public class MountingManager { ThemedReactContext themedReactContext, String componentName, int reactTag, - - boolean isVirtual) { + boolean isLayoutable) { View view = null; ViewManager viewManager = null; - // This can be possible if the view was already pre-allocated - if (mTagToViewState.get(reactTag) != null) return; - - if (!isVirtual) { + if (isLayoutable) { viewManager = mViewManagerRegistry.get(componentName); view = mViewPool.getOrCreateView(componentName, themedReactContext); view.setId(reactTag); @@ -279,12 +275,15 @@ public class MountingManager { ThemedReactContext reactContext, String componentName, int reactTag, - ReadableMap props) { + ReadableMap props, + boolean isLayoutable) { if (mTagToViewState.get(reactTag) != null) return; - createView(reactContext, componentName, reactTag, false); - updateProps(reactTag, props); + createView(reactContext, componentName, reactTag, isLayoutable); + if (isLayoutable) { + updateProps(reactTag, props); + } } @UiThread diff --git a/ReactAndroid/src/main/java/com/facebook/react/fabric/mounting/mountitems/PreAllocateViewMountItem.java b/ReactAndroid/src/main/java/com/facebook/react/fabric/mounting/mountitems/PreAllocateViewMountItem.java index 237b95effe3..fc01ad8ef47 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/fabric/mounting/mountitems/PreAllocateViewMountItem.java +++ b/ReactAndroid/src/main/java/com/facebook/react/fabric/mounting/mountitems/PreAllocateViewMountItem.java @@ -18,19 +18,21 @@ public class PreAllocateViewMountItem implements MountItem { private final int mReactTag; private final ReadableMap mProps; private final ThemedReactContext mContext; + private final boolean mIsLayoutable; public PreAllocateViewMountItem( - ThemedReactContext context, int rootTag, int reactTag, String component, ReadableMap props) { + ThemedReactContext context, int rootTag, int reactTag, String component, ReadableMap props, boolean isLayoutable) { mContext = context; mComponent = component; mRootTag = rootTag; mProps = props; mReactTag = reactTag; + mIsLayoutable = isLayoutable; } @Override public void execute(MountingManager mountingManager) { - mountingManager.preallocateView(mContext, mComponent, mReactTag, mProps); + mountingManager.preallocateView(mContext, mComponent, mReactTag, mProps, mIsLayoutable); } @Override