From 5e1798ad7a56249ec5d64606a3e32e5f80dfe6fd Mon Sep 17 00:00:00 2001 From: Christoph Purrer Date: Tue, 22 Jul 2025 12:30:57 -0700 Subject: [PATCH] Add Android image prefetching feature flag (#52748) Summary: Changelog: [Internal] Pull Request resolved: https://github.com/facebook/react-native/pull/52748 Reviewed By: rshest Differential Revision: D78701936 fbshipit-source-id: 878eed13b39ff71487ca47fe7e4ea46459b85ba3 --- .../featureflags/ReactNativeFeatureFlags.kt | 8 +- .../ReactNativeFeatureFlagsCxxAccessor.kt | 12 ++- .../ReactNativeFeatureFlagsCxxInterop.kt | 4 +- .../ReactNativeFeatureFlagsDefaults.kt | 4 +- .../ReactNativeFeatureFlagsLocalAccessor.kt | 13 ++- .../ReactNativeFeatureFlagsProvider.kt | 4 +- .../facebook/react/uimanager/ViewManager.java | 2 +- .../JReactNativeFeatureFlagsCxxInterop.cpp | 16 ++- .../JReactNativeFeatureFlagsCxxInterop.h | 5 +- .../featureflags/ReactNativeFeatureFlags.cpp | 6 +- .../featureflags/ReactNativeFeatureFlags.h | 7 +- .../ReactNativeFeatureFlagsAccessor.cpp | 100 +++++++++++------- .../ReactNativeFeatureFlagsAccessor.h | 6 +- .../ReactNativeFeatureFlagsDefaults.h | 6 +- .../ReactNativeFeatureFlagsDynamicProvider.h | 11 +- .../ReactNativeFeatureFlagsProvider.h | 3 +- .../NativeReactNativeFeatureFlags.cpp | 7 +- .../NativeReactNativeFeatureFlags.h | 4 +- .../renderer/imagemanager/ImageFetcher.cpp | 4 + .../renderer/imagemanager/ImageFetcher.h | 6 -- .../renderer/imagemanager/ImageManager.cpp | 6 +- .../ReactNativeFeatureFlags.config.js | 11 ++ .../featureflags/ReactNativeFeatureFlags.js | 7 +- .../specs/NativeReactNativeFeatureFlags.js | 3 +- 24 files changed, 187 insertions(+), 68 deletions(-) diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlags.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlags.kt index 7f3d123ba51..9e0ffd62f78 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlags.kt +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlags.kt @@ -4,7 +4,7 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @generated SignedSource<> + * @generated SignedSource<<6f50c9b7a356260abf8afc022aba8fc2>> */ /** @@ -162,6 +162,12 @@ public object ReactNativeFeatureFlags { @JvmStatic public fun enableIOSViewClipToPaddingBox(): Boolean = accessor.enableIOSViewClipToPaddingBox() + /** + * When enabled, Android will build and initiate image prefetch requests on ImageShadowNode::layout + */ + @JvmStatic + public fun enableImagePrefetchingAndroid(): Boolean = accessor.enableImagePrefetchingAndroid() + /** * Dispatches state updates for content offset changes synchronously on the main thread. */ diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsCxxAccessor.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsCxxAccessor.kt index 6c26467ce68..3ff17fcde0e 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsCxxAccessor.kt +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsCxxAccessor.kt @@ -4,7 +4,7 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @generated SignedSource<> + * @generated SignedSource<> */ /** @@ -42,6 +42,7 @@ internal class ReactNativeFeatureFlagsCxxAccessor : ReactNativeFeatureFlagsAcces private var enableFontScaleChangesUpdatingLayoutCache: Boolean? = null private var enableIOSTextBaselineOffsetPerLineCache: Boolean? = null private var enableIOSViewClipToPaddingBoxCache: Boolean? = null + private var enableImagePrefetchingAndroidCache: Boolean? = null private var enableImmediateUpdateModeForContentOffsetChangesCache: Boolean? = null private var enableInteropViewManagerClassLookUpOptimizationIOSCache: Boolean? = null private var enableLayoutAnimationsOnAndroidCache: Boolean? = null @@ -281,6 +282,15 @@ internal class ReactNativeFeatureFlagsCxxAccessor : ReactNativeFeatureFlagsAcces return cached } + override fun enableImagePrefetchingAndroid(): Boolean { + var cached = enableImagePrefetchingAndroidCache + if (cached == null) { + cached = ReactNativeFeatureFlagsCxxInterop.enableImagePrefetchingAndroid() + enableImagePrefetchingAndroidCache = cached + } + return cached + } + override fun enableImmediateUpdateModeForContentOffsetChanges(): Boolean { var cached = enableImmediateUpdateModeForContentOffsetChangesCache if (cached == null) { diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsCxxInterop.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsCxxInterop.kt index be7cbb2a3ae..33f68663097 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsCxxInterop.kt +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsCxxInterop.kt @@ -4,7 +4,7 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @generated SignedSource<> + * @generated SignedSource<> */ /** @@ -72,6 +72,8 @@ public object ReactNativeFeatureFlagsCxxInterop { @DoNotStrip @JvmStatic public external fun enableIOSViewClipToPaddingBox(): Boolean + @DoNotStrip @JvmStatic public external fun enableImagePrefetchingAndroid(): Boolean + @DoNotStrip @JvmStatic public external fun enableImmediateUpdateModeForContentOffsetChanges(): Boolean @DoNotStrip @JvmStatic public external fun enableInteropViewManagerClassLookUpOptimizationIOS(): Boolean diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsDefaults.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsDefaults.kt index cded63ed746..703cb465e3c 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsDefaults.kt +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsDefaults.kt @@ -4,7 +4,7 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @generated SignedSource<> + * @generated SignedSource<> */ /** @@ -67,6 +67,8 @@ public open class ReactNativeFeatureFlagsDefaults : ReactNativeFeatureFlagsProvi override fun enableIOSViewClipToPaddingBox(): Boolean = false + override fun enableImagePrefetchingAndroid(): Boolean = false + override fun enableImmediateUpdateModeForContentOffsetChanges(): Boolean = false override fun enableInteropViewManagerClassLookUpOptimizationIOS(): Boolean = false diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsLocalAccessor.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsLocalAccessor.kt index c3a78715307..f5988c97a2d 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsLocalAccessor.kt +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsLocalAccessor.kt @@ -4,7 +4,7 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @generated SignedSource<<23605f090bfbebe911caa9d3d834d3e8>> + * @generated SignedSource<<1c4bee4de12fc3e38a09f2ddf9b39601>> */ /** @@ -46,6 +46,7 @@ internal class ReactNativeFeatureFlagsLocalAccessor : ReactNativeFeatureFlagsAcc private var enableFontScaleChangesUpdatingLayoutCache: Boolean? = null private var enableIOSTextBaselineOffsetPerLineCache: Boolean? = null private var enableIOSViewClipToPaddingBoxCache: Boolean? = null + private var enableImagePrefetchingAndroidCache: Boolean? = null private var enableImmediateUpdateModeForContentOffsetChangesCache: Boolean? = null private var enableInteropViewManagerClassLookUpOptimizationIOSCache: Boolean? = null private var enableLayoutAnimationsOnAndroidCache: Boolean? = null @@ -307,6 +308,16 @@ internal class ReactNativeFeatureFlagsLocalAccessor : ReactNativeFeatureFlagsAcc return cached } + override fun enableImagePrefetchingAndroid(): Boolean { + var cached = enableImagePrefetchingAndroidCache + if (cached == null) { + cached = currentProvider.enableImagePrefetchingAndroid() + accessedFeatureFlags.add("enableImagePrefetchingAndroid") + enableImagePrefetchingAndroidCache = cached + } + return cached + } + override fun enableImmediateUpdateModeForContentOffsetChanges(): Boolean { var cached = enableImmediateUpdateModeForContentOffsetChangesCache if (cached == null) { diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsProvider.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsProvider.kt index 626f532a496..384df25636d 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsProvider.kt +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsProvider.kt @@ -4,7 +4,7 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @generated SignedSource<<780793412b76f101be1569d7a866c435>> + * @generated SignedSource<<366629baac4727e7db4042a8e9dcab93>> */ /** @@ -67,6 +67,8 @@ public interface ReactNativeFeatureFlagsProvider { @DoNotStrip public fun enableIOSViewClipToPaddingBox(): Boolean + @DoNotStrip public fun enableImagePrefetchingAndroid(): Boolean + @DoNotStrip public fun enableImmediateUpdateModeForContentOffsetChanges(): Boolean @DoNotStrip public fun enableInteropViewManagerClassLookUpOptimizationIOS(): Boolean diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/ViewManager.java b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/ViewManager.java index 28e12d62046..87e56527fa4 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/ViewManager.java +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/ViewManager.java @@ -501,6 +501,6 @@ public abstract class ViewManager @UnstableReactNativeAPI protected boolean experimental_isPrefetchingEnabled() { - return false; + return ReactNativeFeatureFlags.enableImagePrefetchingAndroid(); } } diff --git a/packages/react-native/ReactAndroid/src/main/jni/react/featureflags/JReactNativeFeatureFlagsCxxInterop.cpp b/packages/react-native/ReactAndroid/src/main/jni/react/featureflags/JReactNativeFeatureFlagsCxxInterop.cpp index c6b7230a902..a351bad8a80 100644 --- a/packages/react-native/ReactAndroid/src/main/jni/react/featureflags/JReactNativeFeatureFlagsCxxInterop.cpp +++ b/packages/react-native/ReactAndroid/src/main/jni/react/featureflags/JReactNativeFeatureFlagsCxxInterop.cpp @@ -4,7 +4,7 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @generated SignedSource<> + * @generated SignedSource<<1ec5b2dea32e6f318622cb24a9d66ef2>> */ /** @@ -171,6 +171,12 @@ class ReactNativeFeatureFlagsJavaProvider return method(javaProvider_); } + bool enableImagePrefetchingAndroid() override { + static const auto method = + getReactNativeFeatureFlagsProviderJavaClass()->getMethod("enableImagePrefetchingAndroid"); + return method(javaProvider_); + } + bool enableImmediateUpdateModeForContentOffsetChanges() override { static const auto method = getReactNativeFeatureFlagsProviderJavaClass()->getMethod("enableImmediateUpdateModeForContentOffsetChanges"); @@ -525,6 +531,11 @@ bool JReactNativeFeatureFlagsCxxInterop::enableIOSViewClipToPaddingBox( return ReactNativeFeatureFlags::enableIOSViewClipToPaddingBox(); } +bool JReactNativeFeatureFlagsCxxInterop::enableImagePrefetchingAndroid( + facebook::jni::alias_ref /*unused*/) { + return ReactNativeFeatureFlags::enableImagePrefetchingAndroid(); +} + bool JReactNativeFeatureFlagsCxxInterop::enableImmediateUpdateModeForContentOffsetChanges( facebook::jni::alias_ref /*unused*/) { return ReactNativeFeatureFlags::enableImmediateUpdateModeForContentOffsetChanges(); @@ -822,6 +833,9 @@ void JReactNativeFeatureFlagsCxxInterop::registerNatives() { makeNativeMethod( "enableIOSViewClipToPaddingBox", JReactNativeFeatureFlagsCxxInterop::enableIOSViewClipToPaddingBox), + makeNativeMethod( + "enableImagePrefetchingAndroid", + JReactNativeFeatureFlagsCxxInterop::enableImagePrefetchingAndroid), makeNativeMethod( "enableImmediateUpdateModeForContentOffsetChanges", JReactNativeFeatureFlagsCxxInterop::enableImmediateUpdateModeForContentOffsetChanges), diff --git a/packages/react-native/ReactAndroid/src/main/jni/react/featureflags/JReactNativeFeatureFlagsCxxInterop.h b/packages/react-native/ReactAndroid/src/main/jni/react/featureflags/JReactNativeFeatureFlagsCxxInterop.h index 40d1f051cb1..b968373609b 100644 --- a/packages/react-native/ReactAndroid/src/main/jni/react/featureflags/JReactNativeFeatureFlagsCxxInterop.h +++ b/packages/react-native/ReactAndroid/src/main/jni/react/featureflags/JReactNativeFeatureFlagsCxxInterop.h @@ -4,7 +4,7 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @generated SignedSource<<8c1da07c0b7d2053f7fdaac4326c3ac1>> + * @generated SignedSource<<3570d50c3ff20d976b7145c0c36fd6ac>> */ /** @@ -96,6 +96,9 @@ class JReactNativeFeatureFlagsCxxInterop static bool enableIOSViewClipToPaddingBox( facebook::jni::alias_ref); + static bool enableImagePrefetchingAndroid( + facebook::jni::alias_ref); + static bool enableImmediateUpdateModeForContentOffsetChanges( facebook::jni::alias_ref); diff --git a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlags.cpp b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlags.cpp index 42b02f369b2..8937569d5cd 100644 --- a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlags.cpp +++ b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlags.cpp @@ -4,7 +4,7 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @generated SignedSource<<355265aa8f13e3f307d6e30db6b80d41>> + * @generated SignedSource<<1c8a4501d6e0d7d0b162283cbbdf6a87>> */ /** @@ -114,6 +114,10 @@ bool ReactNativeFeatureFlags::enableIOSViewClipToPaddingBox() { return getAccessor().enableIOSViewClipToPaddingBox(); } +bool ReactNativeFeatureFlags::enableImagePrefetchingAndroid() { + return getAccessor().enableImagePrefetchingAndroid(); +} + bool ReactNativeFeatureFlags::enableImmediateUpdateModeForContentOffsetChanges() { return getAccessor().enableImmediateUpdateModeForContentOffsetChanges(); } diff --git a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlags.h b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlags.h index a9c4098a9a3..a9971efd724 100644 --- a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlags.h +++ b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlags.h @@ -4,7 +4,7 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @generated SignedSource<> + * @generated SignedSource<<3edca00b84d9b4d30c7d9bf5a8dee039>> */ /** @@ -149,6 +149,11 @@ class ReactNativeFeatureFlags { */ RN_EXPORT static bool enableIOSViewClipToPaddingBox(); + /** + * When enabled, Android will build and initiate image prefetch requests on ImageShadowNode::layout + */ + RN_EXPORT static bool enableImagePrefetchingAndroid(); + /** * Dispatches state updates for content offset changes synchronously on the main thread. */ diff --git a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsAccessor.cpp b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsAccessor.cpp index bd652a756da..ffa261884ea 100644 --- a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsAccessor.cpp +++ b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsAccessor.cpp @@ -4,7 +4,7 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @generated SignedSource<> + * @generated SignedSource<<5149f256e2692114e5d4b4efb839589a>> */ /** @@ -425,6 +425,24 @@ bool ReactNativeFeatureFlagsAccessor::enableIOSViewClipToPaddingBox() { return flagValue.value(); } +bool ReactNativeFeatureFlagsAccessor::enableImagePrefetchingAndroid() { + auto flagValue = enableImagePrefetchingAndroid_.load(); + + if (!flagValue.has_value()) { + // This block is not exclusive but it is not necessary. + // If multiple threads try to initialize the feature flag, we would only + // be accessing the provider multiple times but the end state of this + // instance and the returned flag value would be the same. + + markFlagAsAccessed(22, "enableImagePrefetchingAndroid"); + + flagValue = currentProvider_->enableImagePrefetchingAndroid(); + enableImagePrefetchingAndroid_ = flagValue; + } + + return flagValue.value(); +} + bool ReactNativeFeatureFlagsAccessor::enableImmediateUpdateModeForContentOffsetChanges() { auto flagValue = enableImmediateUpdateModeForContentOffsetChanges_.load(); @@ -434,7 +452,7 @@ bool ReactNativeFeatureFlagsAccessor::enableImmediateUpdateModeForContentOffsetC // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(22, "enableImmediateUpdateModeForContentOffsetChanges"); + markFlagAsAccessed(23, "enableImmediateUpdateModeForContentOffsetChanges"); flagValue = currentProvider_->enableImmediateUpdateModeForContentOffsetChanges(); enableImmediateUpdateModeForContentOffsetChanges_ = flagValue; @@ -452,7 +470,7 @@ bool ReactNativeFeatureFlagsAccessor::enableInteropViewManagerClassLookUpOptimiz // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(23, "enableInteropViewManagerClassLookUpOptimizationIOS"); + markFlagAsAccessed(24, "enableInteropViewManagerClassLookUpOptimizationIOS"); flagValue = currentProvider_->enableInteropViewManagerClassLookUpOptimizationIOS(); enableInteropViewManagerClassLookUpOptimizationIOS_ = flagValue; @@ -470,7 +488,7 @@ bool ReactNativeFeatureFlagsAccessor::enableLayoutAnimationsOnAndroid() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(24, "enableLayoutAnimationsOnAndroid"); + markFlagAsAccessed(25, "enableLayoutAnimationsOnAndroid"); flagValue = currentProvider_->enableLayoutAnimationsOnAndroid(); enableLayoutAnimationsOnAndroid_ = flagValue; @@ -488,7 +506,7 @@ bool ReactNativeFeatureFlagsAccessor::enableLayoutAnimationsOnIOS() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(25, "enableLayoutAnimationsOnIOS"); + markFlagAsAccessed(26, "enableLayoutAnimationsOnIOS"); flagValue = currentProvider_->enableLayoutAnimationsOnIOS(); enableLayoutAnimationsOnIOS_ = flagValue; @@ -506,7 +524,7 @@ bool ReactNativeFeatureFlagsAccessor::enableMainQueueCoordinatorOnIOS() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(26, "enableMainQueueCoordinatorOnIOS"); + markFlagAsAccessed(27, "enableMainQueueCoordinatorOnIOS"); flagValue = currentProvider_->enableMainQueueCoordinatorOnIOS(); enableMainQueueCoordinatorOnIOS_ = flagValue; @@ -524,7 +542,7 @@ bool ReactNativeFeatureFlagsAccessor::enableModuleArgumentNSNullConversionIOS() // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(27, "enableModuleArgumentNSNullConversionIOS"); + markFlagAsAccessed(28, "enableModuleArgumentNSNullConversionIOS"); flagValue = currentProvider_->enableModuleArgumentNSNullConversionIOS(); enableModuleArgumentNSNullConversionIOS_ = flagValue; @@ -542,7 +560,7 @@ bool ReactNativeFeatureFlagsAccessor::enableNativeCSSParsing() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(28, "enableNativeCSSParsing"); + markFlagAsAccessed(29, "enableNativeCSSParsing"); flagValue = currentProvider_->enableNativeCSSParsing(); enableNativeCSSParsing_ = flagValue; @@ -560,7 +578,7 @@ bool ReactNativeFeatureFlagsAccessor::enableNetworkEventReporting() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(29, "enableNetworkEventReporting"); + markFlagAsAccessed(30, "enableNetworkEventReporting"); flagValue = currentProvider_->enableNetworkEventReporting(); enableNetworkEventReporting_ = flagValue; @@ -578,7 +596,7 @@ bool ReactNativeFeatureFlagsAccessor::enableNewBackgroundAndBorderDrawables() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(30, "enableNewBackgroundAndBorderDrawables"); + markFlagAsAccessed(31, "enableNewBackgroundAndBorderDrawables"); flagValue = currentProvider_->enableNewBackgroundAndBorderDrawables(); enableNewBackgroundAndBorderDrawables_ = flagValue; @@ -596,7 +614,7 @@ bool ReactNativeFeatureFlagsAccessor::enablePreparedTextLayout() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(31, "enablePreparedTextLayout"); + markFlagAsAccessed(32, "enablePreparedTextLayout"); flagValue = currentProvider_->enablePreparedTextLayout(); enablePreparedTextLayout_ = flagValue; @@ -614,7 +632,7 @@ bool ReactNativeFeatureFlagsAccessor::enablePropsUpdateReconciliationAndroid() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(32, "enablePropsUpdateReconciliationAndroid"); + markFlagAsAccessed(33, "enablePropsUpdateReconciliationAndroid"); flagValue = currentProvider_->enablePropsUpdateReconciliationAndroid(); enablePropsUpdateReconciliationAndroid_ = flagValue; @@ -632,7 +650,7 @@ bool ReactNativeFeatureFlagsAccessor::enableResourceTimingAPI() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(33, "enableResourceTimingAPI"); + markFlagAsAccessed(34, "enableResourceTimingAPI"); flagValue = currentProvider_->enableResourceTimingAPI(); enableResourceTimingAPI_ = flagValue; @@ -650,7 +668,7 @@ bool ReactNativeFeatureFlagsAccessor::enableViewCulling() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(34, "enableViewCulling"); + markFlagAsAccessed(35, "enableViewCulling"); flagValue = currentProvider_->enableViewCulling(); enableViewCulling_ = flagValue; @@ -668,7 +686,7 @@ bool ReactNativeFeatureFlagsAccessor::enableViewRecycling() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(35, "enableViewRecycling"); + markFlagAsAccessed(36, "enableViewRecycling"); flagValue = currentProvider_->enableViewRecycling(); enableViewRecycling_ = flagValue; @@ -686,7 +704,7 @@ bool ReactNativeFeatureFlagsAccessor::enableViewRecyclingForText() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(36, "enableViewRecyclingForText"); + markFlagAsAccessed(37, "enableViewRecyclingForText"); flagValue = currentProvider_->enableViewRecyclingForText(); enableViewRecyclingForText_ = flagValue; @@ -704,7 +722,7 @@ bool ReactNativeFeatureFlagsAccessor::enableViewRecyclingForView() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(37, "enableViewRecyclingForView"); + markFlagAsAccessed(38, "enableViewRecyclingForView"); flagValue = currentProvider_->enableViewRecyclingForView(); enableViewRecyclingForView_ = flagValue; @@ -722,7 +740,7 @@ bool ReactNativeFeatureFlagsAccessor::enableVirtualViewDebugFeatures() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(38, "enableVirtualViewDebugFeatures"); + markFlagAsAccessed(39, "enableVirtualViewDebugFeatures"); flagValue = currentProvider_->enableVirtualViewDebugFeatures(); enableVirtualViewDebugFeatures_ = flagValue; @@ -740,7 +758,7 @@ bool ReactNativeFeatureFlagsAccessor::enableVirtualViewRenderState() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(39, "enableVirtualViewRenderState"); + markFlagAsAccessed(40, "enableVirtualViewRenderState"); flagValue = currentProvider_->enableVirtualViewRenderState(); enableVirtualViewRenderState_ = flagValue; @@ -758,7 +776,7 @@ bool ReactNativeFeatureFlagsAccessor::enableVirtualViewWindowFocusDetection() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(40, "enableVirtualViewWindowFocusDetection"); + markFlagAsAccessed(41, "enableVirtualViewWindowFocusDetection"); flagValue = currentProvider_->enableVirtualViewWindowFocusDetection(); enableVirtualViewWindowFocusDetection_ = flagValue; @@ -776,7 +794,7 @@ bool ReactNativeFeatureFlagsAccessor::fixMappingOfEventPrioritiesBetweenFabricAn // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(41, "fixMappingOfEventPrioritiesBetweenFabricAndReact"); + markFlagAsAccessed(42, "fixMappingOfEventPrioritiesBetweenFabricAndReact"); flagValue = currentProvider_->fixMappingOfEventPrioritiesBetweenFabricAndReact(); fixMappingOfEventPrioritiesBetweenFabricAndReact_ = flagValue; @@ -794,7 +812,7 @@ bool ReactNativeFeatureFlagsAccessor::fuseboxEnabledRelease() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(42, "fuseboxEnabledRelease"); + markFlagAsAccessed(43, "fuseboxEnabledRelease"); flagValue = currentProvider_->fuseboxEnabledRelease(); fuseboxEnabledRelease_ = flagValue; @@ -812,7 +830,7 @@ bool ReactNativeFeatureFlagsAccessor::fuseboxNetworkInspectionEnabled() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(43, "fuseboxNetworkInspectionEnabled"); + markFlagAsAccessed(44, "fuseboxNetworkInspectionEnabled"); flagValue = currentProvider_->fuseboxNetworkInspectionEnabled(); fuseboxNetworkInspectionEnabled_ = flagValue; @@ -830,7 +848,7 @@ bool ReactNativeFeatureFlagsAccessor::hideOffscreenVirtualViewsOnIOS() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(44, "hideOffscreenVirtualViewsOnIOS"); + markFlagAsAccessed(45, "hideOffscreenVirtualViewsOnIOS"); flagValue = currentProvider_->hideOffscreenVirtualViewsOnIOS(); hideOffscreenVirtualViewsOnIOS_ = flagValue; @@ -848,7 +866,7 @@ double ReactNativeFeatureFlagsAccessor::preparedTextCacheSize() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(45, "preparedTextCacheSize"); + markFlagAsAccessed(46, "preparedTextCacheSize"); flagValue = currentProvider_->preparedTextCacheSize(); preparedTextCacheSize_ = flagValue; @@ -866,7 +884,7 @@ bool ReactNativeFeatureFlagsAccessor::preventShadowTreeCommitExhaustionWithLocki // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(46, "preventShadowTreeCommitExhaustionWithLocking"); + markFlagAsAccessed(47, "preventShadowTreeCommitExhaustionWithLocking"); flagValue = currentProvider_->preventShadowTreeCommitExhaustionWithLocking(); preventShadowTreeCommitExhaustionWithLocking_ = flagValue; @@ -884,7 +902,7 @@ bool ReactNativeFeatureFlagsAccessor::releaseImageDataWhenConsumed() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(47, "releaseImageDataWhenConsumed"); + markFlagAsAccessed(48, "releaseImageDataWhenConsumed"); flagValue = currentProvider_->releaseImageDataWhenConsumed(); releaseImageDataWhenConsumed_ = flagValue; @@ -902,7 +920,7 @@ bool ReactNativeFeatureFlagsAccessor::skipActivityIdentityAssertionOnHostPause() // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(48, "skipActivityIdentityAssertionOnHostPause"); + markFlagAsAccessed(49, "skipActivityIdentityAssertionOnHostPause"); flagValue = currentProvider_->skipActivityIdentityAssertionOnHostPause(); skipActivityIdentityAssertionOnHostPause_ = flagValue; @@ -920,7 +938,7 @@ bool ReactNativeFeatureFlagsAccessor::traceTurboModulePromiseRejectionsOnAndroid // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(49, "traceTurboModulePromiseRejectionsOnAndroid"); + markFlagAsAccessed(50, "traceTurboModulePromiseRejectionsOnAndroid"); flagValue = currentProvider_->traceTurboModulePromiseRejectionsOnAndroid(); traceTurboModulePromiseRejectionsOnAndroid_ = flagValue; @@ -938,7 +956,7 @@ bool ReactNativeFeatureFlagsAccessor::updateRuntimeShadowNodeReferencesOnCommit( // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(50, "updateRuntimeShadowNodeReferencesOnCommit"); + markFlagAsAccessed(51, "updateRuntimeShadowNodeReferencesOnCommit"); flagValue = currentProvider_->updateRuntimeShadowNodeReferencesOnCommit(); updateRuntimeShadowNodeReferencesOnCommit_ = flagValue; @@ -956,7 +974,7 @@ bool ReactNativeFeatureFlagsAccessor::useAlwaysAvailableJSErrorHandling() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(51, "useAlwaysAvailableJSErrorHandling"); + markFlagAsAccessed(52, "useAlwaysAvailableJSErrorHandling"); flagValue = currentProvider_->useAlwaysAvailableJSErrorHandling(); useAlwaysAvailableJSErrorHandling_ = flagValue; @@ -974,7 +992,7 @@ bool ReactNativeFeatureFlagsAccessor::useFabricInterop() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(52, "useFabricInterop"); + markFlagAsAccessed(53, "useFabricInterop"); flagValue = currentProvider_->useFabricInterop(); useFabricInterop_ = flagValue; @@ -992,7 +1010,7 @@ bool ReactNativeFeatureFlagsAccessor::useNativeEqualsInNativeReadableArrayAndroi // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(53, "useNativeEqualsInNativeReadableArrayAndroid"); + markFlagAsAccessed(54, "useNativeEqualsInNativeReadableArrayAndroid"); flagValue = currentProvider_->useNativeEqualsInNativeReadableArrayAndroid(); useNativeEqualsInNativeReadableArrayAndroid_ = flagValue; @@ -1010,7 +1028,7 @@ bool ReactNativeFeatureFlagsAccessor::useNativeTransformHelperAndroid() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(54, "useNativeTransformHelperAndroid"); + markFlagAsAccessed(55, "useNativeTransformHelperAndroid"); flagValue = currentProvider_->useNativeTransformHelperAndroid(); useNativeTransformHelperAndroid_ = flagValue; @@ -1028,7 +1046,7 @@ bool ReactNativeFeatureFlagsAccessor::useNativeViewConfigsInBridgelessMode() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(55, "useNativeViewConfigsInBridgelessMode"); + markFlagAsAccessed(56, "useNativeViewConfigsInBridgelessMode"); flagValue = currentProvider_->useNativeViewConfigsInBridgelessMode(); useNativeViewConfigsInBridgelessMode_ = flagValue; @@ -1046,7 +1064,7 @@ bool ReactNativeFeatureFlagsAccessor::useOptimizedEventBatchingOnAndroid() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(56, "useOptimizedEventBatchingOnAndroid"); + markFlagAsAccessed(57, "useOptimizedEventBatchingOnAndroid"); flagValue = currentProvider_->useOptimizedEventBatchingOnAndroid(); useOptimizedEventBatchingOnAndroid_ = flagValue; @@ -1064,7 +1082,7 @@ bool ReactNativeFeatureFlagsAccessor::useRawPropsJsiValue() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(57, "useRawPropsJsiValue"); + markFlagAsAccessed(58, "useRawPropsJsiValue"); flagValue = currentProvider_->useRawPropsJsiValue(); useRawPropsJsiValue_ = flagValue; @@ -1082,7 +1100,7 @@ bool ReactNativeFeatureFlagsAccessor::useShadowNodeStateOnClone() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(58, "useShadowNodeStateOnClone"); + markFlagAsAccessed(59, "useShadowNodeStateOnClone"); flagValue = currentProvider_->useShadowNodeStateOnClone(); useShadowNodeStateOnClone_ = flagValue; @@ -1100,7 +1118,7 @@ bool ReactNativeFeatureFlagsAccessor::useTurboModuleInterop() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(59, "useTurboModuleInterop"); + markFlagAsAccessed(60, "useTurboModuleInterop"); flagValue = currentProvider_->useTurboModuleInterop(); useTurboModuleInterop_ = flagValue; @@ -1118,7 +1136,7 @@ bool ReactNativeFeatureFlagsAccessor::useTurboModules() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(60, "useTurboModules"); + markFlagAsAccessed(61, "useTurboModules"); flagValue = currentProvider_->useTurboModules(); useTurboModules_ = flagValue; @@ -1136,7 +1154,7 @@ double ReactNativeFeatureFlagsAccessor::virtualViewPrerenderRatio() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(61, "virtualViewPrerenderRatio"); + markFlagAsAccessed(62, "virtualViewPrerenderRatio"); flagValue = currentProvider_->virtualViewPrerenderRatio(); virtualViewPrerenderRatio_ = flagValue; diff --git a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsAccessor.h b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsAccessor.h index fb5de307bf7..fe7ab05d3a5 100644 --- a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsAccessor.h +++ b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsAccessor.h @@ -4,7 +4,7 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @generated SignedSource<> + * @generated SignedSource<> */ /** @@ -54,6 +54,7 @@ class ReactNativeFeatureFlagsAccessor { bool enableFontScaleChangesUpdatingLayout(); bool enableIOSTextBaselineOffsetPerLine(); bool enableIOSViewClipToPaddingBox(); + bool enableImagePrefetchingAndroid(); bool enableImmediateUpdateModeForContentOffsetChanges(); bool enableInteropViewManagerClassLookUpOptimizationIOS(); bool enableLayoutAnimationsOnAndroid(); @@ -105,7 +106,7 @@ class ReactNativeFeatureFlagsAccessor { std::unique_ptr currentProvider_; bool wasOverridden_; - std::array, 62> accessedFeatureFlags_; + std::array, 63> accessedFeatureFlags_; std::atomic> commonTestFlag_; std::atomic> cxxNativeAnimatedEnabled_; @@ -129,6 +130,7 @@ class ReactNativeFeatureFlagsAccessor { std::atomic> enableFontScaleChangesUpdatingLayout_; std::atomic> enableIOSTextBaselineOffsetPerLine_; std::atomic> enableIOSViewClipToPaddingBox_; + std::atomic> enableImagePrefetchingAndroid_; std::atomic> enableImmediateUpdateModeForContentOffsetChanges_; std::atomic> enableInteropViewManagerClassLookUpOptimizationIOS_; std::atomic> enableLayoutAnimationsOnAndroid_; diff --git a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsDefaults.h b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsDefaults.h index b90760e874f..e2973572ac5 100644 --- a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsDefaults.h +++ b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsDefaults.h @@ -4,7 +4,7 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @generated SignedSource<<614fe0894f6235d879a0b29e7dab7759>> + * @generated SignedSource<> */ /** @@ -115,6 +115,10 @@ class ReactNativeFeatureFlagsDefaults : public ReactNativeFeatureFlagsProvider { return false; } + bool enableImagePrefetchingAndroid() override { + return false; + } + bool enableImmediateUpdateModeForContentOffsetChanges() override { return false; } diff --git a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsDynamicProvider.h b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsDynamicProvider.h index 7e3a4b7acfb..380f54028c9 100644 --- a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsDynamicProvider.h +++ b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsDynamicProvider.h @@ -4,7 +4,7 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @generated SignedSource<<6502c090532e1d7d2ac67cf6e711d9f4>> + * @generated SignedSource<<44670421b1b5991cd6af3fb7b1c1bf6c>> */ /** @@ -243,6 +243,15 @@ class ReactNativeFeatureFlagsDynamicProvider : public ReactNativeFeatureFlagsDef return ReactNativeFeatureFlagsDefaults::enableIOSViewClipToPaddingBox(); } + bool enableImagePrefetchingAndroid() override { + auto value = values_["enableImagePrefetchingAndroid"]; + if (!value.isNull()) { + return value.getBool(); + } + + return ReactNativeFeatureFlagsDefaults::enableImagePrefetchingAndroid(); + } + bool enableImmediateUpdateModeForContentOffsetChanges() override { auto value = values_["enableImmediateUpdateModeForContentOffsetChanges"]; if (!value.isNull()) { diff --git a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsProvider.h b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsProvider.h index a17afc70ea9..4d4c3145294 100644 --- a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsProvider.h +++ b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsProvider.h @@ -4,7 +4,7 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @generated SignedSource<> + * @generated SignedSource<<082c6d17eec877d054193eb9dea45b6d>> */ /** @@ -47,6 +47,7 @@ class ReactNativeFeatureFlagsProvider { virtual bool enableFontScaleChangesUpdatingLayout() = 0; virtual bool enableIOSTextBaselineOffsetPerLine() = 0; virtual bool enableIOSViewClipToPaddingBox() = 0; + virtual bool enableImagePrefetchingAndroid() = 0; virtual bool enableImmediateUpdateModeForContentOffsetChanges() = 0; virtual bool enableInteropViewManagerClassLookUpOptimizationIOS() = 0; virtual bool enableLayoutAnimationsOnAndroid() = 0; diff --git a/packages/react-native/ReactCommon/react/nativemodule/featureflags/NativeReactNativeFeatureFlags.cpp b/packages/react-native/ReactCommon/react/nativemodule/featureflags/NativeReactNativeFeatureFlags.cpp index baf92be1b71..3a9c53d7e08 100644 --- a/packages/react-native/ReactCommon/react/nativemodule/featureflags/NativeReactNativeFeatureFlags.cpp +++ b/packages/react-native/ReactCommon/react/nativemodule/featureflags/NativeReactNativeFeatureFlags.cpp @@ -4,7 +4,7 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @generated SignedSource<> + * @generated SignedSource<<5b33805daf165bd61f382354685d1d70>> */ /** @@ -154,6 +154,11 @@ bool NativeReactNativeFeatureFlags::enableIOSViewClipToPaddingBox( return ReactNativeFeatureFlags::enableIOSViewClipToPaddingBox(); } +bool NativeReactNativeFeatureFlags::enableImagePrefetchingAndroid( + jsi::Runtime& /*runtime*/) { + return ReactNativeFeatureFlags::enableImagePrefetchingAndroid(); +} + bool NativeReactNativeFeatureFlags::enableImmediateUpdateModeForContentOffsetChanges( jsi::Runtime& /*runtime*/) { return ReactNativeFeatureFlags::enableImmediateUpdateModeForContentOffsetChanges(); diff --git a/packages/react-native/ReactCommon/react/nativemodule/featureflags/NativeReactNativeFeatureFlags.h b/packages/react-native/ReactCommon/react/nativemodule/featureflags/NativeReactNativeFeatureFlags.h index 23df7ab93f0..30b46c17d31 100644 --- a/packages/react-native/ReactCommon/react/nativemodule/featureflags/NativeReactNativeFeatureFlags.h +++ b/packages/react-native/ReactCommon/react/nativemodule/featureflags/NativeReactNativeFeatureFlags.h @@ -4,7 +4,7 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @generated SignedSource<> + * @generated SignedSource<<3487c7ee26cfd5776c85dcf6a6e7fc10>> */ /** @@ -80,6 +80,8 @@ class NativeReactNativeFeatureFlags bool enableIOSViewClipToPaddingBox(jsi::Runtime& runtime); + bool enableImagePrefetchingAndroid(jsi::Runtime& runtime); + bool enableImmediateUpdateModeForContentOffsetChanges(jsi::Runtime& runtime); bool enableInteropViewManagerClassLookUpOptimizationIOS(jsi::Runtime& runtime); diff --git a/packages/react-native/ReactCommon/react/renderer/imagemanager/platform/android/react/renderer/imagemanager/ImageFetcher.cpp b/packages/react-native/ReactCommon/react/renderer/imagemanager/platform/android/react/renderer/imagemanager/ImageFetcher.cpp index f315cbce6d1..26196d91515 100644 --- a/packages/react-native/ReactCommon/react/renderer/imagemanager/platform/android/react/renderer/imagemanager/ImageFetcher.cpp +++ b/packages/react-native/ReactCommon/react/renderer/imagemanager/platform/android/react/renderer/imagemanager/ImageFetcher.cpp @@ -6,7 +6,10 @@ */ #include "ImageFetcher.h" + +#include #include +#include namespace facebook::react { @@ -40,4 +43,5 @@ ImageRequest ImageFetcher::requestImage( return {imageSource, telemetry}; } + } // namespace facebook::react diff --git a/packages/react-native/ReactCommon/react/renderer/imagemanager/platform/android/react/renderer/imagemanager/ImageFetcher.h b/packages/react-native/ReactCommon/react/renderer/imagemanager/platform/android/react/renderer/imagemanager/ImageFetcher.h index ef3e285116b..1869fdef649 100644 --- a/packages/react-native/ReactCommon/react/renderer/imagemanager/platform/android/react/renderer/imagemanager/ImageFetcher.h +++ b/packages/react-native/ReactCommon/react/renderer/imagemanager/platform/android/react/renderer/imagemanager/ImageFetcher.h @@ -7,16 +7,10 @@ #pragma once -#include - -#include -#include #include #include #include -#include - namespace facebook::react { class ImageFetcher { diff --git a/packages/react-native/ReactCommon/react/renderer/imagemanager/platform/android/react/renderer/imagemanager/ImageManager.cpp b/packages/react-native/ReactCommon/react/renderer/imagemanager/platform/android/react/renderer/imagemanager/ImageManager.cpp index 391df87c4a8..d82a33c1e75 100644 --- a/packages/react-native/ReactCommon/react/renderer/imagemanager/platform/android/react/renderer/imagemanager/ImageManager.cpp +++ b/packages/react-native/ReactCommon/react/renderer/imagemanager/platform/android/react/renderer/imagemanager/ImageManager.cpp @@ -6,9 +6,9 @@ */ #include "ImageManager.h" +#include "ImageFetcher.h" #include -#include "ImageFetcher.h" namespace facebook::react { @@ -30,6 +30,10 @@ ImageRequest ImageManager::requestImage( SurfaceId surfaceId, const ImageRequestParams& imageRequestParams, Tag tag) const { + if (ReactNativeFeatureFlags::enableImagePrefetchingAndroid()) { + return static_cast(self_)->requestImage( + imageSource, imageRequestParams, surfaceId, tag); + } return {imageSource, nullptr, {}}; } diff --git a/packages/react-native/scripts/featureflags/ReactNativeFeatureFlags.config.js b/packages/react-native/scripts/featureflags/ReactNativeFeatureFlags.config.js index e23dafa744f..19211078798 100644 --- a/packages/react-native/scripts/featureflags/ReactNativeFeatureFlags.config.js +++ b/packages/react-native/scripts/featureflags/ReactNativeFeatureFlags.config.js @@ -281,6 +281,17 @@ const definitions: FeatureFlagDefinitions = { }, ossReleaseStage: 'none', }, + enableImagePrefetchingAndroid: { + defaultValue: false, + metadata: { + dateAdded: '2025-06-21', + description: + 'When enabled, Android will build and initiate image prefetch requests on ImageShadowNode::layout', + expectedReleaseValue: true, + purpose: 'experimentation', + }, + ossReleaseStage: 'none', + }, enableImmediateUpdateModeForContentOffsetChanges: { defaultValue: false, metadata: { diff --git a/packages/react-native/src/private/featureflags/ReactNativeFeatureFlags.js b/packages/react-native/src/private/featureflags/ReactNativeFeatureFlags.js index 110148e3c1a..0aa34258fe7 100644 --- a/packages/react-native/src/private/featureflags/ReactNativeFeatureFlags.js +++ b/packages/react-native/src/private/featureflags/ReactNativeFeatureFlags.js @@ -4,7 +4,7 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @generated SignedSource<> + * @generated SignedSource<> * @flow strict * @noformat */ @@ -68,6 +68,7 @@ export type ReactNativeFeatureFlags = $ReadOnly<{ enableFontScaleChangesUpdatingLayout: Getter, enableIOSTextBaselineOffsetPerLine: Getter, enableIOSViewClipToPaddingBox: Getter, + enableImagePrefetchingAndroid: Getter, enableImmediateUpdateModeForContentOffsetChanges: Getter, enableInteropViewManagerClassLookUpOptimizationIOS: Getter, enableLayoutAnimationsOnAndroid: Getter, @@ -257,6 +258,10 @@ export const enableIOSTextBaselineOffsetPerLine: Getter = createNativeF * iOS Views will clip to their padding box vs border box */ export const enableIOSViewClipToPaddingBox: Getter = createNativeFlagGetter('enableIOSViewClipToPaddingBox', false); +/** + * When enabled, Android will build and initiate image prefetch requests on ImageShadowNode::layout + */ +export const enableImagePrefetchingAndroid: Getter = createNativeFlagGetter('enableImagePrefetchingAndroid', false); /** * Dispatches state updates for content offset changes synchronously on the main thread. */ diff --git a/packages/react-native/src/private/featureflags/specs/NativeReactNativeFeatureFlags.js b/packages/react-native/src/private/featureflags/specs/NativeReactNativeFeatureFlags.js index 9a95c16f32a..58c71c9562a 100644 --- a/packages/react-native/src/private/featureflags/specs/NativeReactNativeFeatureFlags.js +++ b/packages/react-native/src/private/featureflags/specs/NativeReactNativeFeatureFlags.js @@ -4,7 +4,7 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @generated SignedSource<<45c98e5f4b5f3d3a8a0ded4c5148b549>> + * @generated SignedSource<<8051b5c10479f9ad92faad99586578d9>> * @flow strict * @noformat */ @@ -47,6 +47,7 @@ export interface Spec extends TurboModule { +enableFontScaleChangesUpdatingLayout?: () => boolean; +enableIOSTextBaselineOffsetPerLine?: () => boolean; +enableIOSViewClipToPaddingBox?: () => boolean; + +enableImagePrefetchingAndroid?: () => boolean; +enableImmediateUpdateModeForContentOffsetChanges?: () => boolean; +enableInteropViewManagerClassLookUpOptimizationIOS?: () => boolean; +enableLayoutAnimationsOnAndroid?: () => boolean;