Skip to content

_relayoutBoundary is more complex than it could be, and undocumented #150524

@gnprice

Description

@gnprice

The other day I started studying RenderObject and related code to understand how the rendering library tracks which objects need layout, and in particular just how the concept of "relayout boundary" works.

  1. The RenderObject._relayoutBoundary property itself currently has no docs. Having done the work to understand it, I'll send a PR to add some.
    Document RenderObject._relayoutBoundary and its invariant; small refactors #150527

  2. Then after staring at that code hard enough to be able to write docs for it, I realized that its logic could be simplified: instead of a RenderObject? _relayoutBoundary which points at the (ancestor that is the) nearest enclosing relayout boundary, we could track just a bool? _isRelayoutBoundary that says whether this render object itself is a relayout boundary.
    Reduce relayout-boundary tracking to a bool-or-null per RenderObject #150905

  3. Further, after switching from a RenderObject? to a bool?, it becomes possible to skip walking the tree to update the property on layout. For example in A--B--[big subtree] where A is the relayout boundary, if in laying out B we decide that B is now a relayout boundary, we currently need to walk the whole subtree to update all the descendants to point to B instead of A. But if each of those nodes instead records only that it itself isn't a relayout boundary, then that fact didn't change and there's no need for the walk.

    Skipping those walks is enough to get a small but measurable performance win: in a microbenchmark with a linear tree of 4000 nested objects, measured on a Pixel 8, it reduces the total time to compute each frame by about 41%, or in absolute terms a bit over 0.1ms per frame. So I plan to send follow-up PRs to do that.

    → for the benchmarks, Add benchmarks for tracking relayout boundaries #150539

  4. After that, there are a couple of further simplifications I have my eye on. We walk the tree on dropChild, and I think that becomes unnecessary; cutting that makes another measurable performance win.

  5. Finally, the logic mostly treats null the same as false. (Already on main, where it's in terms of _relayoutBoundary, it mostly treats null the same as non-null values other than this.) So I'd like to collapse that distinction and make it just a bool; or else understand more crisply why the distinction should remain, and then document that.

Metadata

Metadata

Assignees

Labels

P3Issues that are less important to the Flutter projectframeworkflutter/packages/flutter repository. See also f: labels.team-frameworkOwned by Framework teamtriaged-frameworkTriaged by Framework team

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions