mirror of
https://github.com/facebook/react-native.git
synced 2025-11-01 09:14:26 +00:00
Perf improvement: don't call uiManager.updateRootLayoutSpecs on every ReactRootView.onLayout
Summary: In D23640968 (https://github.com/facebook/react-native/commit/78b42d7fb7180102c1e8ec917dcccd2d9d4076db) I introduced a mechanism to update offsetX/offsetY whenever onMeasure/onLayout were called, to ensure that `measureInWindow` had the correct metrics and would work properly. However, now `uiManager.updateRootLayoutSpecs` gets spammed and is called too often. For example, whenever a TextInput is focused/blurred, `uiManager.updateRootLayoutSpecs` may be called 5+ times even though the measure specs/offsets may only change once. Thus, we just compare with previous values before calling into the UIManager. This should give us a very small perf improvement. Changelog: [Internal] Reviewed By: shergin Differential Revision: D24176867 fbshipit-source-id: f0dcc816e651a843607e9e5d40d8f3489894d4ba
This commit is contained in:
committed by
Facebook GitHub Bot
parent
7c2f46ce3f
commit
c547757913
@@ -95,6 +95,8 @@ public class ReactRootView extends FrameLayout implements RootView, ReactRoot {
|
||||
private int mHeightMeasureSpec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);
|
||||
private int mLastWidth = 0;
|
||||
private int mLastHeight = 0;
|
||||
private int mLastOffsetX = Integer.MIN_VALUE;
|
||||
private int mLastOffsetY = Integer.MIN_VALUE;
|
||||
private @UIManagerType int mUIManagerType = DEFAULT;
|
||||
|
||||
public ReactRootView(Context context) {
|
||||
@@ -162,7 +164,7 @@ public class ReactRootView extends FrameLayout implements RootView, ReactRoot {
|
||||
if (mReactInstanceManager != null && !mIsAttachedToInstance) {
|
||||
attachToReactInstanceManager();
|
||||
} else if (measureSpecsUpdated || mLastWidth != width || mLastHeight != height) {
|
||||
updateRootLayoutSpecs(mWidthMeasureSpec, mHeightMeasureSpec);
|
||||
updateRootLayoutSpecs(true, mWidthMeasureSpec, mHeightMeasureSpec);
|
||||
}
|
||||
mLastWidth = width;
|
||||
mLastHeight = height;
|
||||
@@ -296,7 +298,7 @@ public class ReactRootView extends FrameLayout implements RootView, ReactRoot {
|
||||
|
||||
// In Fabric, update LayoutSpecs just so we update the offsetX and offsetY.
|
||||
if (mWasMeasured && getUIManagerType() == FABRIC) {
|
||||
updateRootLayoutSpecs(mWidthMeasureSpec, mHeightMeasureSpec);
|
||||
updateRootLayoutSpecs(false, mWidthMeasureSpec, mHeightMeasureSpec);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -423,7 +425,17 @@ public class ReactRootView extends FrameLayout implements RootView, ReactRoot {
|
||||
return new Point(locationInWindow[0], locationInWindow[1]);
|
||||
}
|
||||
|
||||
private void updateRootLayoutSpecs(final int widthMeasureSpec, final int heightMeasureSpec) {
|
||||
/**
|
||||
* Call whenever measure specs change, or if you want to force an update of offsetX/offsetY. If
|
||||
* measureSpecsChanged is false and the offsetX/offsetY don't change, updateRootLayoutSpecs will
|
||||
* not be called on the UIManager as a perf optimization.
|
||||
*
|
||||
* @param measureSpecsChanged
|
||||
* @param widthMeasureSpec
|
||||
* @param heightMeasureSpec
|
||||
*/
|
||||
private void updateRootLayoutSpecs(
|
||||
boolean measureSpecsChanged, final int widthMeasureSpec, final int heightMeasureSpec) {
|
||||
if (mReactInstanceManager == null) {
|
||||
FLog.w(TAG, "Unable to update root layout specs for uninitialized ReactInstanceManager");
|
||||
return;
|
||||
@@ -445,8 +457,12 @@ public class ReactRootView extends FrameLayout implements RootView, ReactRoot {
|
||||
offsetY = viewportOffset.y;
|
||||
}
|
||||
|
||||
uiManager.updateRootLayoutSpecs(
|
||||
getRootViewTag(), widthMeasureSpec, heightMeasureSpec, offsetX, offsetY);
|
||||
if (measureSpecsChanged || offsetX != mLastOffsetX || offsetY != mLastOffsetY) {
|
||||
uiManager.updateRootLayoutSpecs(
|
||||
getRootViewTag(), widthMeasureSpec, heightMeasureSpec, offsetX, offsetY);
|
||||
}
|
||||
mLastOffsetX = offsetX;
|
||||
mLastOffsetY = offsetY;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -558,7 +574,7 @@ public class ReactRootView extends FrameLayout implements RootView, ReactRoot {
|
||||
String jsAppModuleName = getJSModuleName();
|
||||
|
||||
if (mWasMeasured) {
|
||||
updateRootLayoutSpecs(mWidthMeasureSpec, mHeightMeasureSpec);
|
||||
updateRootLayoutSpecs(true, mWidthMeasureSpec, mHeightMeasureSpec);
|
||||
}
|
||||
|
||||
WritableNativeMap appParams = new WritableNativeMap();
|
||||
|
||||
Reference in New Issue
Block a user