diff --git a/ReactCommon/fabric/components/slider/SliderComponentDescriptor.h b/ReactCommon/fabric/components/slider/SliderComponentDescriptor.h index 48d40d317..8265249bc 100644 --- a/ReactCommon/fabric/components/slider/SliderComponentDescriptor.h +++ b/ReactCommon/fabric/components/slider/SliderComponentDescriptor.h @@ -36,7 +36,9 @@ class SliderComponentDescriptor final imageManager_(nullptr), #endif measurementsManager_( - std::make_shared(contextContainer)) { + SliderMeasurementsManager::shouldMeasureSlider() + ? std::make_shared(contextContainer) + : nullptr) { } void adopt(UnsharedShadowNode shadowNode) const override { @@ -50,13 +52,15 @@ class SliderComponentDescriptor final // communicate the loading state and results to mounting layer. sliderShadowNode->setImageManager(imageManager_); - // `SliderShadowNode` uses `SliderMeasurementsManager` to - // provide measurements to Yoga. - sliderShadowNode->setSliderMeasurementsManager(measurementsManager_); + if (measurementsManager_) { + // `SliderShadowNode` uses `SliderMeasurementsManager` to + // provide measurements to Yoga. + sliderShadowNode->setSliderMeasurementsManager(measurementsManager_); - // All `SliderShadowNode`s must have leaf Yoga nodes with properly - // setup measure function. - sliderShadowNode->enableMeasurement(); + // All `SliderShadowNode`s must have leaf Yoga nodes with properly + // setup measure function. + sliderShadowNode->enableMeasurement(); + } } private: diff --git a/ReactCommon/fabric/components/slider/SliderShadowNode.cpp b/ReactCommon/fabric/components/slider/SliderShadowNode.cpp index 8932ef2a3..a5fd45cc7 100644 --- a/ReactCommon/fabric/components/slider/SliderShadowNode.cpp +++ b/ReactCommon/fabric/components/slider/SliderShadowNode.cpp @@ -93,7 +93,7 @@ ImageSource SliderShadowNode::getThumbImageSource() const { #pragma mark - LayoutableShadowNode Size SliderShadowNode::measure(LayoutConstraints layoutConstraints) const { - if (measurementsManager_->shouldMeasureSlider()) { + if (SliderMeasurementsManager::shouldMeasureSlider()) { return measurementsManager_->measure(layoutConstraints); } diff --git a/ReactCommon/fabric/components/slider/platform/android/SliderMeasurementsManager.cpp b/ReactCommon/fabric/components/slider/platform/android/SliderMeasurementsManager.cpp index 07782a774..9f7cf72cc 100644 --- a/ReactCommon/fabric/components/slider/platform/android/SliderMeasurementsManager.cpp +++ b/ReactCommon/fabric/components/slider/platform/android/SliderMeasurementsManager.cpp @@ -16,12 +16,15 @@ using namespace facebook::jni; namespace facebook { namespace react { -const bool SliderMeasurementsManager::shouldMeasureSlider() const { - return true; -} - Size SliderMeasurementsManager::measure( LayoutConstraints layoutConstraints) const { + { + std::lock_guard lock(mutex_); + if (hasBeenMeasured_) { + return cachedMeasurement_; + } + } + const jni::global_ref &fabricUIManager = contextContainer_->getInstance>( "FabricUIManager"); @@ -46,7 +49,7 @@ Size SliderMeasurementsManager::measure( local_ref componentName = make_jstring("RCTSlider"); - return yogaMeassureToSize(measure( + auto measurement = yogaMeassureToSize(measure( fabricUIManager, componentName.get(), nullptr, @@ -55,6 +58,10 @@ Size SliderMeasurementsManager::measure( maxWidth, minHeight, maxHeight)); + + std::lock_guard lock(mutex_); + cachedMeasurement_ = measurement; + return measurement; } } // namespace react diff --git a/ReactCommon/fabric/components/slider/platform/android/SliderMeasurementsManager.h b/ReactCommon/fabric/components/slider/platform/android/SliderMeasurementsManager.h index 55076a093..d0515264a 100644 --- a/ReactCommon/fabric/components/slider/platform/android/SliderMeasurementsManager.h +++ b/ReactCommon/fabric/components/slider/platform/android/SliderMeasurementsManager.h @@ -22,11 +22,18 @@ class SliderMeasurementsManager { public: SliderMeasurementsManager(const SharedContextContainer &contextContainer) : contextContainer_(contextContainer) {} - const bool shouldMeasureSlider() const; + + static inline bool shouldMeasureSlider() { + return true; + } + Size measure(LayoutConstraints layoutConstraints) const; private: const SharedContextContainer contextContainer_; + mutable std::mutex mutex_; + mutable bool hasBeenMeasured_ = false; + mutable Size cachedMeasurement_{}; }; } // namespace react diff --git a/ReactCommon/fabric/components/slider/platform/ios/SliderMeasurementsManager.cpp b/ReactCommon/fabric/components/slider/platform/ios/SliderMeasurementsManager.cpp index 6112e4fc9..8d7fc1706 100644 --- a/ReactCommon/fabric/components/slider/platform/ios/SliderMeasurementsManager.cpp +++ b/ReactCommon/fabric/components/slider/platform/ios/SliderMeasurementsManager.cpp @@ -10,10 +10,6 @@ namespace facebook { namespace react { -const bool SliderMeasurementsManager::shouldMeasureSlider() const { - return false; -} - Size SliderMeasurementsManager::measure( LayoutConstraints layoutConstraints) const { assert(false); // should never reach this point diff --git a/ReactCommon/fabric/components/slider/platform/ios/SliderMeasurementsManager.h b/ReactCommon/fabric/components/slider/platform/ios/SliderMeasurementsManager.h index 3f253718d..2571886ed 100644 --- a/ReactCommon/fabric/components/slider/platform/ios/SliderMeasurementsManager.h +++ b/ReactCommon/fabric/components/slider/platform/ios/SliderMeasurementsManager.h @@ -21,7 +21,11 @@ namespace react { class SliderMeasurementsManager { public: SliderMeasurementsManager(const SharedContextContainer &contextContainer) {} - const bool shouldMeasureSlider() const; + + static inline bool shouldMeasureSlider() { + return false; + } + Size measure(LayoutConstraints layoutConstraints) const; };