Skip to content

Commit 2b02acd

Browse files
committed
optimize layout performance
1 parent d55de1c commit 2b02acd

File tree

1 file changed

+92
-45
lines changed

1 file changed

+92
-45
lines changed

lib/src/constraint_layout.dart

Lines changed: 92 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -823,19 +823,23 @@ class Constraint {
823823
bool needsLayout = false;
824824
bool needsPaint = false;
825825
bool needsReorderChildren = false;
826+
bool needsRecalculateConstraints = false;
826827

827828
if (parentData.id != id) {
828829
parentData.id = id;
830+
needsRecalculateConstraints = true;
829831
needsLayout = true;
830832
}
831833

832834
if (parentData.width != width) {
833835
parentData.width = width;
836+
needsRecalculateConstraints = true;
834837
needsLayout = true;
835838
}
836839

837840
if (parentData.height != height) {
838841
parentData.height = height;
842+
needsRecalculateConstraints = true;
839843
needsLayout = true;
840844
}
841845

@@ -867,26 +871,31 @@ class Constraint {
867871

868872
if (parentData.left != left) {
869873
parentData.left = left;
874+
needsRecalculateConstraints = true;
870875
needsLayout = true;
871876
}
872877

873878
if (parentData.right != right) {
874879
parentData.right = right;
880+
needsRecalculateConstraints = true;
875881
needsLayout = true;
876882
}
877883

878884
if (parentData.top != top) {
879885
parentData.top = top;
886+
needsRecalculateConstraints = true;
880887
needsLayout = true;
881888
}
882889

883890
if (parentData.bottom != bottom) {
884891
parentData.bottom = bottom;
892+
needsRecalculateConstraints = true;
885893
needsLayout = true;
886894
}
887895

888896
if (parentData.baseline != baseline) {
889897
parentData.baseline = baseline;
898+
needsRecalculateConstraints = true;
890899
needsLayout = true;
891900
}
892901

@@ -897,8 +906,8 @@ class Constraint {
897906

898907
if (parentData.zIndex != zIndex) {
899908
parentData.zIndex = zIndex;
900-
needsPaint = true;
901909
needsReorderChildren = true;
910+
needsPaint = true;
902911
}
903912

904913
if (parentData.translateConstraint != translateConstraint) {
@@ -979,6 +988,11 @@ class Constraint {
979988

980989
if (needsLayout) {
981990
AbstractNode? targetParent = renderObject.parent;
991+
if (needsRecalculateConstraints) {
992+
if (targetParent is _ConstraintRenderBox) {
993+
targetParent.markNeedsRecalculateConstraints();
994+
}
995+
}
982996
if (targetParent is RenderObject) {
983997
targetParent.markNeedsLayout();
984998
}
@@ -1134,8 +1148,14 @@ class _ConstraintRenderBox extends RenderBox
11341148
late bool _debugShowZIndex;
11351149
late bool _needsReorderChildren;
11361150

1151+
bool _needsRecalculateConstraints = true;
11371152
final Map<RenderBox, _ConstrainedNode> _constrainedNodes = HashMap();
11381153
final Map<ConstraintId, _ConstrainedNode> _tempConstrainedNodes = HashMap();
1154+
1155+
/// For layout
1156+
late List<_ConstrainedNode> _layoutOrderList;
1157+
1158+
/// for paint
11391159
late List<_ConstrainedNode> _paintingOrderList;
11401160

11411161
static const int maxTimeUsage = 20;
@@ -1156,6 +1176,7 @@ class _ConstraintRenderBox extends RenderBox
11561176
}
11571177
if (!isSameList) {
11581178
_childConstraints = value;
1179+
markNeedsRecalculateConstraints();
11591180
markNeedsLayout();
11601181
}
11611182
}
@@ -1177,6 +1198,7 @@ class _ConstraintRenderBox extends RenderBox
11771198
set debugPrintConstraints(bool value) {
11781199
if (_debugPrintConstraints != value) {
11791200
_debugPrintConstraints = value;
1201+
markNeedsRecalculateConstraints();
11801202
markNeedsLayout();
11811203
}
11821204
}
@@ -1191,6 +1213,7 @@ class _ConstraintRenderBox extends RenderBox
11911213
set debugCheckConstraints(bool value) {
11921214
if (_debugCheckConstraints != value) {
11931215
_debugCheckConstraints = value;
1216+
markNeedsRecalculateConstraints();
11941217
markNeedsLayout();
11951218
}
11961219
}
@@ -1205,6 +1228,7 @@ class _ConstraintRenderBox extends RenderBox
12051228
set debugName(String? value) {
12061229
if (_debugName != value) {
12071230
_debugName = value;
1231+
markNeedsRecalculateConstraints();
12081232
markNeedsLayout();
12091233
}
12101234
}
@@ -1453,6 +1477,22 @@ class _ConstraintRenderBox extends RenderBox
14531477
}
14541478
}
14551479

1480+
@override
1481+
void adoptChild(covariant RenderObject child) {
1482+
super.adoptChild(child);
1483+
markNeedsRecalculateConstraints();
1484+
}
1485+
1486+
@override
1487+
void dropChild(covariant RenderObject child) {
1488+
super.dropChild(child);
1489+
markNeedsRecalculateConstraints();
1490+
}
1491+
1492+
void markNeedsRecalculateConstraints() {
1493+
_needsRecalculateConstraints = true;
1494+
}
1495+
14561496
@override
14571497
void performLayout() {
14581498
int startTime = 0;
@@ -1468,7 +1508,6 @@ class _ConstraintRenderBox extends RenderBox
14681508

14691509
/// Always fill the parent layout
14701510
/// TODO will support wrap_content in the future
1471-
14721511
double consMaxWidth = constraints.maxWidth;
14731512
if (consMaxWidth == double.infinity) {
14741513
consMaxWidth = window.physicalSize.width / window.devicePixelRatio;
@@ -1479,51 +1518,57 @@ class _ConstraintRenderBox extends RenderBox
14791518
}
14801519
size = constraints.constrain(Size(consMaxWidth, consMaxHeight));
14811520

1482-
assert(() {
1483-
if (_debugCheckConstraints) {
1484-
_debugCheckIds();
1485-
}
1486-
return true;
1487-
}());
1521+
if (_needsRecalculateConstraints) {
1522+
assert(() {
1523+
if (_debugCheckConstraints) {
1524+
_debugCheckIds();
1525+
}
1526+
return true;
1527+
}());
14881528

1489-
/// Traverse once, building the constrained node tree for each child element
1490-
_buildConstrainedNodeTrees();
1529+
/// Traverse once, building the constrained node tree for each child element
1530+
_buildConstrainedNodeTrees();
14911531

1492-
assert(() {
1493-
if (_debugCheckConstraints) {
1494-
_debugCheckConstraintsIntegrity();
1495-
_debugCheckLoopConstraints();
1496-
}
1497-
return true;
1498-
}());
1532+
assert(() {
1533+
if (_debugCheckConstraints) {
1534+
_debugCheckConstraintsIntegrity();
1535+
_debugCheckLoopConstraints();
1536+
}
1537+
return true;
1538+
}());
14991539

1500-
/// Sort by the depth of constraint from shallow to deep, the lowest depth is 0, representing parent
1501-
List<_ConstrainedNode> constrainedNodeTrees =
1502-
_constrainedNodes.values.toList();
1503-
constrainedNodeTrees.sort((left, right) {
1504-
return left.getDepth() - right.getDepth();
1505-
});
1506-
1507-
_paintingOrderList = _constrainedNodes.values.toList();
1508-
_paintingOrderList.sort((left, right) {
1509-
int result = left.zIndex - right.zIndex;
1510-
if (result == 0) {
1511-
result = left.index - right.index;
1512-
}
1513-
return result;
1514-
});
1515-
_needsReorderChildren = false;
1540+
/// Sort by the depth of constraint from shallow to deep, the lowest depth is 0, representing parent
1541+
_layoutOrderList = _constrainedNodes.values.toList();
1542+
_paintingOrderList = _constrainedNodes.values.toList();
1543+
_constrainedNodes.clear();
15161544

1517-
assert(() {
1518-
/// Print constraints
1519-
if (_debugPrintConstraints) {
1520-
debugPrint('ConstraintLayout@${_debugName ?? hashCode} constraints: ' +
1521-
jsonEncode(constrainedNodeTrees.map((e) => e.toJson()).toList()));
1522-
}
1523-
return true;
1524-
}());
1545+
_layoutOrderList.sort((left, right) {
1546+
return left.getDepth() - right.getDepth();
1547+
});
1548+
1549+
_paintingOrderList.sort((left, right) {
1550+
int result = left.zIndex - right.zIndex;
1551+
if (result == 0) {
1552+
result = left.index - right.index;
1553+
}
1554+
return result;
1555+
});
1556+
1557+
assert(() {
1558+
/// Print constraints
1559+
if (_debugPrintConstraints) {
1560+
debugPrint(
1561+
'ConstraintLayout@${_debugName ?? hashCode} constraints: ' +
1562+
jsonEncode(_layoutOrderList.map((e) => e.toJson()).toList()));
1563+
}
1564+
return true;
1565+
}());
1566+
1567+
_needsReorderChildren = false;
1568+
_needsRecalculateConstraints = false;
1569+
}
15251570

1526-
_layoutByConstrainedNodeTrees(constrainedNodeTrees);
1571+
_layoutByConstrainedNodeTrees();
15271572

15281573
if (_releasePrintLayoutTime && kReleaseMode) {
15291574
layoutTimeUsage.add(DateTime.now().millisecondsSinceEpoch - startTime);
@@ -1606,9 +1651,8 @@ class _ConstraintRenderBox extends RenderBox
16061651
_getBottomInsets(insets, percentageMargin, anchorHeight);
16071652
}
16081653

1609-
void _layoutByConstrainedNodeTrees(
1610-
List<_ConstrainedNode> constrainedNodeTrees) {
1611-
for (final element in constrainedNodeTrees) {
1654+
void _layoutByConstrainedNodeTrees() {
1655+
for (final element in _layoutOrderList) {
16121656
EdgeInsets margin = element.margin;
16131657
EdgeInsets goneMargin = element.goneMargin;
16141658

@@ -2706,6 +2750,7 @@ class _GuidelineRenderBox extends _InternalBox {
27062750
if (_id != value) {
27072751
_id = value;
27082752
updateParentData();
2753+
(this.parent as _ConstraintRenderBox).markNeedsRecalculateConstraints();
27092754
markParentNeedsLayout();
27102755
}
27112756
}
@@ -2880,6 +2925,7 @@ class _BarrierRenderBox extends _InternalBox {
28802925
if (_id != value) {
28812926
_id = value;
28822927
updateParentData();
2928+
(this.parent as _ConstraintRenderBox).markNeedsRecalculateConstraints();
28832929
markParentNeedsLayout();
28842930
}
28852931
}
@@ -2907,6 +2953,7 @@ class _BarrierRenderBox extends _InternalBox {
29072953
if (!isSameList) {
29082954
_referencedIds = value;
29092955
updateParentData();
2956+
(this.parent as _ConstraintRenderBox).markNeedsRecalculateConstraints();
29102957
markParentNeedsLayout();
29112958
}
29122959
}

0 commit comments

Comments
 (0)