diff --git a/ReactCommon/fabric/components/root/RootShadowNode.cpp b/ReactCommon/fabric/components/root/RootShadowNode.cpp index 7226afe6015..74a93a2f536 100644 --- a/ReactCommon/fabric/components/root/RootShadowNode.cpp +++ b/ReactCommon/fabric/components/root/RootShadowNode.cpp @@ -15,9 +15,14 @@ namespace react { const char RootComponentName[] = "RootView"; -void RootShadowNode::layout( +bool RootShadowNode::layoutIfNeeded( std::vector *affectedNodes) { SystraceSection s("RootShadowNode::layout"); + + if (getIsLayoutClean()) { + return false; + } + ensureUnsealed(); auto layoutContext = getProps()->layoutContext; @@ -31,6 +36,8 @@ void RootShadowNode::layout( setLayoutMetrics(layoutMetricsFromYogaNode(yogaNode_)); setHasNewLayout(false); } + + return true; } RootShadowNode::Unshared RootShadowNode::clone( diff --git a/ReactCommon/fabric/components/root/RootShadowNode.h b/ReactCommon/fabric/components/root/RootShadowNode.h index 1e2761cc2a6..cb45c793cf7 100644 --- a/ReactCommon/fabric/components/root/RootShadowNode.h +++ b/ReactCommon/fabric/components/root/RootShadowNode.h @@ -35,9 +35,11 @@ class RootShadowNode final using Unshared = std::shared_ptr; /* - * Layouts the shadow tree. + * Layouts the shadow tree if needed. + * Returns `false` if the three is already laid out. */ - void layout(std::vector *affectedNodes = {}); + bool layoutIfNeeded( + std::vector *affectedNodes = {}); /* * Clones the node with given `layoutConstraints` and `layoutContext`. @@ -58,9 +60,6 @@ class RootShadowNode final ShadowNodeFamily const &shadowNodeFamily, std::function callback) const; - - private: - using YogaLayoutableShadowNode::layout; }; } // namespace react diff --git a/ReactCommon/fabric/mounting/ShadowTree.cpp b/ReactCommon/fabric/mounting/ShadowTree.cpp index 97d741b3bac..0d55bbfbae8 100644 --- a/ReactCommon/fabric/mounting/ShadowTree.cpp +++ b/ReactCommon/fabric/mounting/ShadowTree.cpp @@ -169,7 +169,7 @@ bool ShadowTree::tryCommit(ShadowTreeCommitTransaction transaction) const { affectedLayoutableNodes.reserve(1024); telemetry.willLayout(); - newRootShadowNode->layout(&affectedLayoutableNodes); + newRootShadowNode->layoutIfNeeded(&affectedLayoutableNodes); telemetry.didLayout(); newRootShadowNode->sealRecursive(); diff --git a/ReactCommon/fabric/mounting/tests/ShadowTreeLifeCycleTest.cpp b/ReactCommon/fabric/mounting/tests/ShadowTreeLifeCycleTest.cpp index f298b80f75f..e263f68b08a 100644 --- a/ReactCommon/fabric/mounting/tests/ShadowTreeLifeCycleTest.cpp +++ b/ReactCommon/fabric/mounting/tests/ShadowTreeLifeCycleTest.cpp @@ -92,7 +92,7 @@ static void testShadowNodeTreeLifeCycle( // Laying out the tree. std::const_pointer_cast(nextRootNode) - ->layout(&affectedLayoutableNodes); + ->layoutIfNeeded(&affectedLayoutableNodes); nextRootNode->sealRecursive(); allNodes.push_back(nextRootNode); diff --git a/ReactCommon/fabric/uimanager/Scheduler.cpp b/ReactCommon/fabric/uimanager/Scheduler.cpp index 833cf3ad5b1..29ce6dc7bc8 100644 --- a/ReactCommon/fabric/uimanager/Scheduler.cpp +++ b/ReactCommon/fabric/uimanager/Scheduler.cpp @@ -234,7 +234,7 @@ Size Scheduler::measureSurface( [&](RootShadowNode::Shared const &oldRootShadowNode) { auto rootShadowNode = oldRootShadowNode->clone(layoutConstraints, layoutContext); - rootShadowNode->layout(); + rootShadowNode->layoutIfNeeded(); size = rootShadowNode->getLayoutMetrics().frame.size; return nullptr; });