mirror of
https://github.com/zhigang1992/react-native.git
synced 2026-01-12 22:50:10 +08:00
Fabric: Being smarter preserving dirty flag on Yoga nodes
Summary: After the change, YogaLayoutableShadowNode will preserve dirty flag (being false) in cases where: * a node was cloned with same children; * changes in props don't affect layout. Motivation: In Fabric we always were aggressive about dirting yoga nodes: when we clone the node, we always dirty underlying Yoga node. I think that was the case because we don't deeply understand how the system works and we always had more severe problems to fix. Now, we faced an issue that forces us to think about that problem carefully (more about that later). (I don't expect that will improve TTI performance, but that's possible if we do a lot of changes in the hierarchy during initial load process.) I see two main use cases where we have to be smart about dirtied yoga nodes: Case 1. Native local commits which do *not* modify yoga styles.E.g. in a case where ScrollView updates the internal state (which has offset info) really really frequently. (It will be implemented later.) That `contentOffset` info does not or might not affect layout, so we should not pay for this. Case 2. Legit React commits which do *not* modify yoga styles. E.g. in a case where only the background color of some view changes, we don't need to relayout anything. Unfortunately, we do this in Fabric because of two major reasons: * We don't make a difference between any changes in Props. * React constructs new children of cloned node iteratively, calling `appendChild`. That makes implementing optimization really challenging because we don't know when the process ends. And when it ends we have very few pieces of information about how the state looked before. This diff stack will handle the problems of the first kind. The main motivation is: we want to have state updates to be as lean as possible. Reviewed By: JoshuaGross Differential Revision: D14472752 fbshipit-source-id: 68374f60cb07de9ab65bf1f6d94c828985359fa5
This commit is contained in:
committed by
Facebook Github Bot
parent
62d340910a
commit
d6d381180b
@@ -37,7 +37,8 @@ YogaLayoutableShadowNode::YogaLayoutableShadowNode(
|
||||
yogaNode_.setConfig(&yogaConfig_);
|
||||
yogaNode_.setContext(this);
|
||||
yogaNode_.setOwner(nullptr);
|
||||
yogaNode_.setDirty(true);
|
||||
// Yoga node must inherit dirty flag.
|
||||
assert(layoutableShadowNode.yogaNode_.isDirty() == yogaNode_.isDirty());
|
||||
}
|
||||
|
||||
void YogaLayoutableShadowNode::cleanLayout() {
|
||||
@@ -72,6 +73,8 @@ void YogaLayoutableShadowNode::enableMeasurement() {
|
||||
void YogaLayoutableShadowNode::appendChild(YogaLayoutableShadowNode *child) {
|
||||
ensureUnsealed();
|
||||
|
||||
yogaNode_.setDirty(true);
|
||||
|
||||
auto yogaNodeRawPtr = &yogaNode_;
|
||||
auto childYogaNodeRawPtr = &child->yogaNode_;
|
||||
|
||||
@@ -91,6 +94,9 @@ void YogaLayoutableShadowNode::appendChild(YogaLayoutableShadowNode *child) {
|
||||
|
||||
void YogaLayoutableShadowNode::setChildren(
|
||||
YogaLayoutableShadowNode::UnsharedList children) {
|
||||
ensureUnsealed();
|
||||
yogaNode_.setDirty(true);
|
||||
|
||||
yogaNode_.setChildren({});
|
||||
for (const auto &child : children) {
|
||||
appendChild(child);
|
||||
@@ -98,6 +104,13 @@ void YogaLayoutableShadowNode::setChildren(
|
||||
}
|
||||
|
||||
void YogaLayoutableShadowNode::setProps(const YogaStylableProps &props) {
|
||||
ensureUnsealed();
|
||||
|
||||
// Resetting `dirty` flag only if `yogaStyle` portion of `Props` was changed.
|
||||
if (!yogaNode_.isDirty() && (props.yogaStyle != yogaNode_.getStyle())) {
|
||||
yogaNode_.setDirty(true);
|
||||
}
|
||||
|
||||
yogaNode_.setStyle(props.yogaStyle);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user