From 4bb33f93cd0d25c7334ec9412abd90af38d22557 Mon Sep 17 00:00:00 2001 From: Ahmed El-Helw Date: Thu, 2 Jun 2016 14:02:50 -0700 Subject: [PATCH] Promote grandchildren of certain views are Views Summary: As an optimization, for something like a ScrollView which contains a FlatViewGroup containing posts, make sure that each post is explicitly mounted to a View. This may help improve performance, especially when said Views are otherwise inlined as DrawCommands instead of actual Views. Reviewed By: astreet Differential Revision: D3161232 --- .../facebook/react/flat/FlatShadowNode.java | 24 +++++++++++++++++++ .../react/flat/NativeViewWrapper.java | 7 ++++-- 2 files changed, 29 insertions(+), 2 deletions(-) diff --git a/ReactAndroid/src/main/java/com/facebook/react/flat/FlatShadowNode.java b/ReactAndroid/src/main/java/com/facebook/react/flat/FlatShadowNode.java index 8483706f0f..6b1016a905 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/flat/FlatShadowNode.java +++ b/ReactAndroid/src/main/java/com/facebook/react/flat/FlatShadowNode.java @@ -11,6 +11,7 @@ package com.facebook.react.flat; import javax.annotation.Nullable; +import com.facebook.csslayout.CSSNode; import com.facebook.infer.annotation.Assertions; import com.facebook.react.uimanager.LayoutShadowNode; import com.facebook.react.uimanager.OnLayoutEvent; @@ -55,6 +56,7 @@ import com.facebook.react.views.view.ReactClippingViewGroupHelper; private @Nullable DrawBackgroundColor mDrawBackground; private boolean mClipToBounds = false; private boolean mIsUpdated = true; + private boolean mForceMountChildrenToView; private float mClipLeft; private float mClipTop; private float mClipRight; @@ -89,6 +91,20 @@ import com.facebook.react.views.view.ReactClippingViewGroupHelper; } } + /* package */ final void forceMountChildrenToView() { + if (mForceMountChildrenToView) { + return; + } + + mForceMountChildrenToView = true; + for (int i = 0, childCount = getChildCount(); i != childCount; ++i) { + ReactShadowNode child = getChildAt(i); + if (child instanceof FlatShadowNode) { + ((FlatShadowNode) child).forceMountToView(); + } + } + } + /** * Collects DrawCommands produced by this FlatShadowNode. */ @@ -157,6 +173,14 @@ import com.facebook.react.views.view.ReactClippingViewGroupHelper; return mViewBottom - mViewTop; } + @Override + public void addChildAt(CSSNode child, int i) { + super.addChildAt(child, i); + if (mForceMountChildrenToView && child instanceof FlatShadowNode) { + ((FlatShadowNode) child).forceMountToView(); + } + } + /** * Marks root node as updated to trigger a StateBuilder pass to collect DrawCommands for the node * tree. Use it when FlatShadowNode is updated but doesn't require a layout pass (e.g. background diff --git a/ReactAndroid/src/main/java/com/facebook/react/flat/NativeViewWrapper.java b/ReactAndroid/src/main/java/com/facebook/react/flat/NativeViewWrapper.java index 4d87dd9e5c..08cf9db061 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/flat/NativeViewWrapper.java +++ b/ReactAndroid/src/main/java/com/facebook/react/flat/NativeViewWrapper.java @@ -23,6 +23,7 @@ import com.facebook.react.uimanager.ViewManager; @Nullable private final ReactShadowNode mReactShadowNode; private final boolean mNeedsCustomLayoutForChildren; private boolean mPaddingChanged = false; + private boolean mForceMountGrandChildrenToView; /* package */ NativeViewWrapper(ViewManager viewManager) { ReactShadowNode reactShadowNode = viewManager.createShadowNodeInstance(); @@ -36,11 +37,13 @@ import com.facebook.react.uimanager.ViewManager; if (viewManager instanceof ViewGroupManager) { ViewGroupManager viewGroupManager = (ViewGroupManager) viewManager; mNeedsCustomLayoutForChildren = viewGroupManager.needsCustomLayoutForChildren(); + mForceMountGrandChildrenToView = viewGroupManager.shouldPromoteGrandchildren(); } else { mNeedsCustomLayoutForChildren = false; } forceMountToView(); + forceMountChildrenToView(); } @Override @@ -82,8 +85,8 @@ import com.facebook.react.uimanager.ViewManager; @Override public void addChildAt(CSSNode child, int i) { super.addChildAt(child, i); - if (child instanceof FlatShadowNode) { - ((FlatShadowNode) child).forceMountToView(); + if (mForceMountGrandChildrenToView && child instanceof FlatShadowNode) { + ((FlatShadowNode) child).forceMountChildrenToView(); } }