From 6bd67de4d33e75876f813b07a04628aafdd224b7 Mon Sep 17 00:00:00 2001 From: Valentin Shergin Date: Mon, 18 Mar 2019 19:16:38 -0700 Subject: [PATCH] Fabric: Being even smarter preserving dirty flag on Yoga nodes Summary: In addition to the previous change, now we handle a situation where some node receives a new set of children and all those children have the same styles. (See the previous diff for more details.) Reviewed By: JoshuaGross Differential Revision: D14472754 fbshipit-source-id: 16411036e14f18e730e064e33948440b05ff51c8 --- .../view/yoga/YogaLayoutableShadowNode.cpp | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/ReactCommon/fabric/components/view/yoga/YogaLayoutableShadowNode.cpp b/ReactCommon/fabric/components/view/yoga/YogaLayoutableShadowNode.cpp index e2837b7d2d6..8ce8af565f9 100644 --- a/ReactCommon/fabric/components/view/yoga/YogaLayoutableShadowNode.cpp +++ b/ReactCommon/fabric/components/view/yoga/YogaLayoutableShadowNode.cpp @@ -95,12 +95,25 @@ void YogaLayoutableShadowNode::appendChild(YogaLayoutableShadowNode *child) { void YogaLayoutableShadowNode::setChildren( YogaLayoutableShadowNode::UnsharedList children) { ensureUnsealed(); - yogaNode_.setDirty(true); + + // Optimization: + // If the new list of child nodes consists of clean nodes, and if their styles + // are identical to styles of old children, we don't dirty the node. + bool isClean = !yogaNode_.getDirtied() && + children.size() == yogaNode_.getChildren().size(); + auto oldChildren = isClean ? yogaNode_.getChildren() : YGVector{}; yogaNode_.setChildren({}); - for (const auto &child : children) { + + auto i = int{0}; + for (auto const &child : children) { appendChild(child); + + isClean = isClean && !child->yogaNode_.isDirty() && + child->yogaNode_.getStyle() == oldChildren[i++]->getStyle(); } + + yogaNode_.setDirty(!isClean); } void YogaLayoutableShadowNode::setProps(const YogaStylableProps &props) {