mirror of
https://github.com/facebook/react-native.git
synced 2025-11-01 09:14:26 +00:00
Ship "state update scroll race" to ScrollView and HorizontalScrollView
Summary: As a followup to T91209139, ship "state update scroll race" in code. This also ships it for HorizontalScrollView since it's been validated for vertical scroll views. Changelog: [Internal] Reviewed By: sammy-SC Differential Revision: D29595601 fbshipit-source-id: 64b6a23e2dab2c13123e132d9d899fb769d03172
This commit is contained in:
committed by
Facebook GitHub Bot
parent
421df26266
commit
4ad4426daf
@@ -69,17 +69,4 @@ public class ReactFeatureFlags {
|
||||
public static boolean enableLockFreeEventDispatcher = false;
|
||||
|
||||
public static boolean enableAggressiveEventEmitterCleanup = false;
|
||||
|
||||
//
|
||||
// ScrollView C++ UpdateState vs onScroll race fixes
|
||||
//
|
||||
|
||||
/* Enables a "state race condition fix" for ScrollViews StateUpdate + onScroll event emitter */
|
||||
public static boolean enableScrollViewStateEventRaceFix = false;
|
||||
|
||||
/* Enables another "state race condition fix" for ScrollViews StateUpdate + onScroll event emitter. Races a StateUpdate with every onScroll event. */
|
||||
public static boolean enableScrollViewStateEventAlwaysRace = false;
|
||||
|
||||
/* Configure a min scroll delta for UpdateState to be called while still actively scrolling. */
|
||||
public static int scrollViewUpdateStateMinScrollDelta = 0;
|
||||
}
|
||||
|
||||
+6
@@ -417,6 +417,12 @@ public class ReactHorizontalScrollView extends HorizontalScrollView
|
||||
updateClippingRect();
|
||||
}
|
||||
|
||||
// Race an UpdateState with every onScroll. This makes it more likely that, in Fabric,
|
||||
// when JS processes the scroll event, the C++ ShadowNode representation will have a
|
||||
// "more correct" scroll position. It will frequently be /incorrect/ but this decreases
|
||||
// the error as much as possible.
|
||||
updateStateOnScroll();
|
||||
|
||||
ReactScrollViewHelper.emitScrollEvent(
|
||||
this,
|
||||
mOnScrollDispatchHelper.getXFlingVelocity(),
|
||||
|
||||
@@ -30,7 +30,6 @@ import com.facebook.react.bridge.ReactContext;
|
||||
import com.facebook.react.bridge.WritableMap;
|
||||
import com.facebook.react.bridge.WritableNativeMap;
|
||||
import com.facebook.react.common.ReactConstants;
|
||||
import com.facebook.react.config.ReactFeatureFlags;
|
||||
import com.facebook.react.uimanager.FabricViewStateManager;
|
||||
import com.facebook.react.uimanager.MeasureSpecAssertions;
|
||||
import com.facebook.react.uimanager.PixelUtil;
|
||||
@@ -101,7 +100,6 @@ public class ReactScrollView extends ScrollView
|
||||
|
||||
private int mScrollAwayPaddingTop = 0;
|
||||
|
||||
private boolean mWaitingForStateUpdateRoundTrip = false;
|
||||
private int mLastStateUpdateScrollX = -1;
|
||||
private int mLastStateUpdateScrollY = -1;
|
||||
|
||||
@@ -288,22 +286,16 @@ public class ReactScrollView extends ScrollView
|
||||
updateClippingRect();
|
||||
}
|
||||
|
||||
// Another potential UpdateState vs onScroll fix: race an UpdateState with every onScroll
|
||||
// TODO T91209139: if this mechanism works well, port it to HorizontalScrollView
|
||||
if (ReactFeatureFlags.enableScrollViewStateEventAlwaysRace) {
|
||||
updateStateOnScroll();
|
||||
}
|
||||
// Race an UpdateState with every onScroll. This makes it more likely that, in Fabric,
|
||||
// when JS processes the scroll event, the C++ ShadowNode representation will have a
|
||||
// "more correct" scroll position. It will frequently be /incorrect/ but this decreases
|
||||
// the error as much as possible.
|
||||
updateStateOnScroll();
|
||||
|
||||
// TODO T91209139: if this mechanism works well, port it to HorizontalScrollView
|
||||
boolean deferEvent =
|
||||
ReactFeatureFlags.enableScrollViewStateEventRaceFix
|
||||
&& (mWaitingForStateUpdateRoundTrip || updateStateOnScroll());
|
||||
if (!deferEvent) {
|
||||
ReactScrollViewHelper.emitScrollEvent(
|
||||
this,
|
||||
mOnScrollDispatchHelper.getXFlingVelocity(),
|
||||
mOnScrollDispatchHelper.getYFlingVelocity());
|
||||
}
|
||||
ReactScrollViewHelper.emitScrollEvent(
|
||||
this,
|
||||
mOnScrollDispatchHelper.getXFlingVelocity(),
|
||||
mOnScrollDispatchHelper.getYFlingVelocity());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1013,23 +1005,6 @@ public class ReactScrollView extends ScrollView
|
||||
setRemoveClippedSubviews(mRemoveClippedSubviews);
|
||||
}
|
||||
|
||||
/**
|
||||
* If we know we are sending a State update, we defer emitting scroll events until the State
|
||||
* update makes it back to Java. When that happens, we should immediately emit the scroll event.
|
||||
*/
|
||||
void onStateUpdate() {
|
||||
mWaitingForStateUpdateRoundTrip = false;
|
||||
|
||||
// For now we don't dedupe these - we want to send an event whenever the metrics have changed
|
||||
// from the perspective of C++
|
||||
if (ReactFeatureFlags.enableScrollViewStateEventRaceFix) {
|
||||
ReactScrollViewHelper.emitScrollEvent(
|
||||
this,
|
||||
mOnScrollDispatchHelper.getXFlingVelocity(),
|
||||
mOnScrollDispatchHelper.getYFlingVelocity());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Called on any stabilized onScroll change to propagate content offset value to a Shadow Node.
|
||||
*/
|
||||
@@ -1043,20 +1018,9 @@ public class ReactScrollView extends ScrollView
|
||||
return false;
|
||||
}
|
||||
|
||||
// Require a certain delta if we're still scrolling
|
||||
if (mActivelyScrolling) {
|
||||
int MIN_DELTA_TO_UPDATE_SCROLL_STATE = ReactFeatureFlags.scrollViewUpdateStateMinScrollDelta;
|
||||
int deltaX = Math.abs(mLastStateUpdateScrollX - scrollX);
|
||||
int deltaY = Math.abs(mLastStateUpdateScrollY - scrollY);
|
||||
if (deltaX < MIN_DELTA_TO_UPDATE_SCROLL_STATE && deltaY < MIN_DELTA_TO_UPDATE_SCROLL_STATE) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
mLastStateUpdateScrollX = scrollX;
|
||||
mLastStateUpdateScrollY = scrollY;
|
||||
|
||||
mWaitingForStateUpdateRoundTrip = true;
|
||||
forceUpdateState();
|
||||
|
||||
return true;
|
||||
|
||||
@@ -325,7 +325,6 @@ public class ReactScrollViewManager extends ViewGroupManager<ReactScrollView>
|
||||
public Object updateState(
|
||||
ReactScrollView view, ReactStylesDiffMap props, @Nullable StateWrapper stateWrapper) {
|
||||
view.getFabricViewStateManager().setStateWrapper(stateWrapper);
|
||||
view.onStateUpdate();
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user