Skip to content

Commit

Permalink
Optimize pre-allocation of views
Browse files Browse the repository at this point in the history
Summary: This diff changes the way pre-allocation of views are executed in Fabric. Before this diff the execution of view preallocation was schedulled at the end of the UIThread queue, now the views are pre-allocated in the next "tick"

Reviewed By: sahrens

Differential Revision: D13857614

fbshipit-source-id: 386bf966d3c8a0d5c0bd626119a92810465aecb7
  • Loading branch information
mdvacca authored and facebook-github-bot committed Jan 30, 2019
1 parent 4c69ccd commit 16a6e51
Show file tree
Hide file tree
Showing 3 changed files with 65 additions and 17 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
import com.facebook.react.fabric.mounting.mountitems.DispatchCommandMountItem;
import com.facebook.react.fabric.mounting.mountitems.InsertMountItem;
import com.facebook.react.fabric.mounting.mountitems.MountItem;
import com.facebook.react.fabric.mounting.mountitems.PreAllocateViewMountItem;
import com.facebook.react.fabric.mounting.mountitems.RemoveMountItem;
import com.facebook.react.fabric.mounting.mountitems.UpdateEventEmitterMountItem;
import com.facebook.react.fabric.mounting.mountitems.UpdateLayoutMountItem;
Expand All @@ -49,6 +50,7 @@
import com.facebook.react.bridge.WritableMap;
import com.facebook.react.common.ReactConstants;
import com.facebook.react.modules.core.ReactChoreographer;
import com.facebook.react.uimanager.IllegalViewOperationException;
import com.facebook.react.uimanager.ReactRootViewTagGenerator;
import com.facebook.react.uimanager.ThemedReactContext;
import com.facebook.react.uimanager.ViewManagerPropertyUpdater;
Expand Down Expand Up @@ -94,10 +96,14 @@ public class FabricUIManager implements UIManager, LifecycleEventListener {
new ConcurrentHashMap<>();
private final EventBeatManager mEventBeatManager;
private final Object mMountItemsLock = new Object();
private final Object mPreMountItemsLock = new Object();

@GuardedBy("mMountItemsLock")
private List<MountItem> mMountItems = new ArrayList<>();

@GuardedBy("mPreMountItemsLock")
private List<MountItem> mPreMountItems = new ArrayList<>();

@ThreadConfined(UI)
private final DispatchUIFrameCallback mDispatchUIFrameCallback;

Expand Down Expand Up @@ -177,17 +183,13 @@ public void onCatalystInstanceDestroy() {

@DoNotStrip
private void preallocateView(final int rootTag, final String componentName) {
UiThreadUtil.runOnUiThread(
new GuardedRunnable(mReactApplicationContext) {
@Override
public void runGuarded() {
ThemedReactContext context =
Assertions.assertNotNull(mReactContextForRootTag.get(rootTag));
String component = sComponentNames.get(componentName);
Assertions.assertNotNull(component);
mMountingManager.preallocateView(context, component);
}
});
synchronized (mPreMountItemsLock) {
ThemedReactContext context =
Assertions.assertNotNull(mReactContextForRootTag.get(rootTag));
String component = sComponentNames.get(componentName);
Assertions.assertNotNull(component);
mPreMountItems.add(new PreAllocateViewMountItem(context, rootTag, component));
}
}

@DoNotStrip
Expand Down Expand Up @@ -286,25 +288,35 @@ private void flushMountItems() {
}

try {
List<MountItem> preMountItemsToDispatch;
synchronized (mPreMountItemsLock) {
preMountItemsToDispatch = mPreMountItems;
mPreMountItems = new ArrayList<>();
}

List<MountItem> mountItemsToDispatch;
synchronized (mMountItemsLock) {
if (mMountItems.isEmpty()) {
return;
}
mountItemsToDispatch = mMountItems;
mMountItems = new ArrayList<>();
}

Systrace.beginSection(
Systrace.TRACE_TAG_REACT_JAVA_BRIDGE,
"FabricUIManager::premountViews (" + preMountItemsToDispatch.size() + " batches)");
for (MountItem mountItem : preMountItemsToDispatch) {
mountItem.execute(mMountingManager);
}
Systrace.endSection(Systrace.TRACE_TAG_REACT_JAVA_BRIDGE);

Systrace.beginSection(
Systrace.TRACE_TAG_REACT_JAVA_BRIDGE,
"FabricUIManager::mountViews (" + mountItemsToDispatch.size() + " batches)");
for (MountItem mountItem : mountItemsToDispatch) {
mountItem.execute(mMountingManager);
}

Systrace.endSection(Systrace.TRACE_TAG_REACT_JAVA_BRIDGE);
} catch (Exception ex) {
FLog.i(ReactConstants.TAG, "Exception thrown when executing UIFrameGuarded", ex);
FLog.e(ReactConstants.TAG, "Exception thrown when executing UIFrameGuarded", ex);
mIsMountingEnabled = false;
throw ex;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@
*/
package com.facebook.react.fabric.mounting.mountitems;

import com.facebook.react.fabric.mounting.MountingManager;
import com.facebook.proguard.annotations.DoNotStrip;
import com.facebook.react.fabric.mounting.MountingManager;
import com.facebook.systrace.Systrace;

/**
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
/**
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
package com.facebook.react.fabric.mounting.mountitems;

import com.facebook.react.fabric.mounting.MountingManager;
import com.facebook.react.uimanager.ThemedReactContext;

/**
* {@link MountItem} that is used to pre-allocate views for JS components.
*/
public class PreAllocateViewMountItem implements MountItem {

private final String mComponent;
private final int mRootTag;
private final ThemedReactContext mContext;

public PreAllocateViewMountItem(ThemedReactContext context, int rootTag, String component){
mContext = context;
mComponent = component;
mRootTag = rootTag;
}

@Override
public void execute(MountingManager mountingManager) {
mountingManager.preallocateView(mContext, mComponent);
}

@Override
public String toString() {
return "[" + mRootTag + "] - Preallocate " + mComponent;
}
}

0 comments on commit 16a6e51

Please sign in to comment.