From f30716323af98e8626990b10840b0843bced6ea1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rub=C3=A9n=20Norte?= Date: Fri, 26 May 2023 09:06:00 -0700 Subject: [PATCH] Add flag to do granular state updates in scroll views in iOS (#37461) Summary: Pull Request resolved: https://github.com/facebook/react-native/pull/37461 This adds a feature flag to dispatch state updates for scroll position in every scroll position update in iOS, as opposed to only at the beginning, end and other specific moments. This is necessary to implement features like `IntersectionObserver`, but we want to test the performance impact of this change before rolling it out completely. Changelog: [internal] Reviewed By: javache Differential Revision: D45916675 fbshipit-source-id: 00a2b1c5ea03e45141bb2d81e4e5fb8c198de1ff --- .../ComponentViews/ScrollView/RCTScrollViewComponentView.mm | 2 +- packages/react-native/React/Fabric/RCTSurfacePresenter.mm | 4 ++++ .../ReactCommon/react/renderer/core/CoreFeatures.cpp | 1 + .../ReactCommon/react/renderer/core/CoreFeatures.h | 4 ++++ 4 files changed, 10 insertions(+), 1 deletion(-) diff --git a/packages/react-native/React/Fabric/Mounting/ComponentViews/ScrollView/RCTScrollViewComponentView.mm b/packages/react-native/React/Fabric/Mounting/ComponentViews/ScrollView/RCTScrollViewComponentView.mm index d8ee6cb3d8b..fde373ba822 100644 --- a/packages/react-native/React/Fabric/Mounting/ComponentViews/ScrollView/RCTScrollViewComponentView.mm +++ b/packages/react-native/React/Fabric/Mounting/ComponentViews/ScrollView/RCTScrollViewComponentView.mm @@ -437,7 +437,7 @@ static void RCTSendScrollEventForNativeAnimations_DEPRECATED(UIScrollView *scrol - (void)scrollViewDidScroll:(UIScrollView *)scrollView { - if (!_isUserTriggeredScrolling) { + if (!_isUserTriggeredScrolling || CoreFeatures::enableGranularScrollViewStateUpdatesIOS) { [self _updateStateWithContentOffset]; } diff --git a/packages/react-native/React/Fabric/RCTSurfacePresenter.mm b/packages/react-native/React/Fabric/RCTSurfacePresenter.mm index 7b09c995700..8608d8b042f 100644 --- a/packages/react-native/React/Fabric/RCTSurfacePresenter.mm +++ b/packages/react-native/React/Fabric/RCTSurfacePresenter.mm @@ -276,6 +276,10 @@ static BackgroundExecutor RCTGetBackgroundExecutor() CoreFeatures::disableTransactionCommit = true; } + if (reactNativeConfig && reactNativeConfig->getBool("react_fabric:enable_granular_scroll_view_state_updates_ios")) { + CoreFeatures::enableGranularScrollViewStateUpdatesIOS = true; + } + auto componentRegistryFactory = [factory = wrapManagedObject(_mountingManager.componentViewRegistry.componentViewFactory)]( EventDispatcher::Weak const &eventDispatcher, ContextContainer::Shared const &contextContainer) { diff --git a/packages/react-native/ReactCommon/react/renderer/core/CoreFeatures.cpp b/packages/react-native/ReactCommon/react/renderer/core/CoreFeatures.cpp index 351a257d678..cbfd5cf3b10 100644 --- a/packages/react-native/ReactCommon/react/renderer/core/CoreFeatures.cpp +++ b/packages/react-native/ReactCommon/react/renderer/core/CoreFeatures.cpp @@ -16,5 +16,6 @@ bool CoreFeatures::useNativeState = false; bool CoreFeatures::cacheLastTextMeasurement = false; bool CoreFeatures::cancelImageDownloadsOnRecycle = false; bool CoreFeatures::disableTransactionCommit = false; +bool CoreFeatures::enableGranularScrollViewStateUpdatesIOS = false; } // namespace facebook::react diff --git a/packages/react-native/ReactCommon/react/renderer/core/CoreFeatures.h b/packages/react-native/ReactCommon/react/renderer/core/CoreFeatures.h index f9a07875d27..a204428d15d 100644 --- a/packages/react-native/ReactCommon/react/renderer/core/CoreFeatures.h +++ b/packages/react-native/ReactCommon/react/renderer/core/CoreFeatures.h @@ -48,6 +48,10 @@ class CoreFeatures { // [CATransaction end] This feature flag disables it to measure its impact in // production. static bool disableTransactionCommit; + + // When enabled, RCTScrollViewComponentView will trigger ShadowTree state + // updates for all changes in scroll position. + static bool enableGranularScrollViewStateUpdatesIOS; }; } // namespace facebook::react