Force execution of all pre-allocation of views before execution of mount items

Summary:
Now that pre-allocation of views update props, we can just force the execution of "pre-allocation" instead of "create" mount item.

This should reduce the amount of mountItems that are created during commit phase.
This should improve TTI (I'm running a MobileLab)

Reviewed By: shergin

Differential Revision: D14297476

fbshipit-source-id: 3ade662848ed836dc3221abe78611bb4a2b94e00
This commit is contained in:
David Vacca 2019-03-03 15:47:08 -08:00 коммит произвёл Facebook Github Bot
Родитель ca6e1793ed
Коммит 861e406097
4 изменённых файлов: 37 добавлений и 55 удалений

Просмотреть файл

@ -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<MountItem> 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<MountItem> 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)");

Просмотреть файл

@ -166,34 +166,6 @@ local_ref<JString> getPlatformComponentName(const ShadowView& shadowView) {
return componentName;
}
local_ref<JMountItem::javaobject> createCreateMountItem(
const jni::global_ref<jobject>& javaUIManager,
const ShadowViewMutation& mutation,
const Tag rootTag) {
static auto createJavaInstruction =
jni::findClassStatic(UIManagerJavaDescriptor)
->getMethod<alias_ref<JMountItem>(jstring, jint, jint, jboolean, ReadableMap::javaobject)>(
"createMountItem");
auto newChildShadowView = mutation.newChildShadowView;
local_ref<JString> componentName =
getPlatformComponentName(newChildShadowView);
jboolean isVirtual = newChildShadowView.layoutMetrics == EmptyLayoutMetrics;
local_ref<ReadableMap::javaobject> 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<JMountItem::javaobject> createUpdateEventEmitterMountItem(
const jni::global_ref<jobject>& 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<void(jint, jint, jstring, ReadableMap::javaobject)>("preallocateView");
static auto preallocateView =
jni::findClassStatic(UIManagerJavaDescriptor)
->getMethod<void(jint, jint, jstring, ReadableMap::javaobject, jboolean)>("preallocateView");
local_ref<ReadableMap::javaobject> readableMap =
castReadableMap(ReadableNativeMap::newObjectCxxArgs(shadowView.props->rawProps));
preallocateView(
javaUIManager_, surfaceId, shadowView.tag, make_jstring(shadowView.componentName).get(), readableMap.get());
}
local_ref<ReadableMap::javaobject> readableMap =
castReadableMap(ReadableNativeMap::newObjectCxxArgs(shadowView.props->rawProps));
preallocateView(
javaUIManager_, surfaceId, shadowView.tag, make_jstring(shadowView.componentName).get(), readableMap.get(), isLayoutableShadowNode);
}
void Binding::registerNatives() {

Просмотреть файл

@ -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

Просмотреть файл

@ -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