boxy icon indicating copy to clipboard operation
boxy copied to clipboard

Ignore layout for somes childs ?

Open RomanJos opened this issue 3 years ago • 2 comments

Hello, I was just wondering if is was possible to avoid a layout for some child ? I have one child that need to be resized based on a animation value and currently everything is in the layout method.

Here is a small video to illustrate a bit : https://user-images.githubusercontent.com/42180076/187019036-5fd2e168-72c0-4c8e-a875-1d65d26d23e1.mp4

Thank you !

RomanJos avatar Aug 27 '22 07:08 RomanJos

You can't avoid calling layout on children, however, the framework does implement optimizations that short-circuit it for you.

If the constraints passed to a child are the same as in the previous layout (and markNeedsLayout wasn't called) then the framework skips calling performLayout: see if (!_needsLayout && constraints == _constraints) { in https://api.flutter.dev/flutter/rendering/RenderObject/layout.html

pingbird avatar Aug 27 '22 15:08 pingbird

That is great to hear ! I definitely see an improvement (250 to 80 micro-seconds !) by having the same constraints object for all the children.

However, it appears that, all the widgets still repaints, I already have a RepaintBoundary on the moving wave but they are still painting on window resize or on the animation no matter if the constraints are the same, and only by giving the "has to resize" widget the same constraint the performance move to 80.

image

Only by giving the same constraints to the third widget the time drop, green and blue are when only the third and everyone have the same constraints between layouts, red and yellow are when only the two or nobody have the same constraints between layouts.

I'm a bit lost here :

  • BoxConstraints == operator check if the value reference to the same objects before looking at maxHeight etc. I'm using constraints.copyWith() so the yellow line would differ from the red, even slightly ? (It look like it does a bit lol)
  • Why the blue and green don't too ?
  • I placed a CustomPainter in the "has to not" and it paint every times, even with the same constraints object.
  • The "has to resize" widget is so simple yet add (250-80) micro-seconds to the layout method.
// The entire top widget
class Salut extends StatefulWidget {
  const Salut({Key? key}) : super(key: key);

  @override
  State<Salut> createState() => _SalutState();
}

class _SalutState extends State<Salut> {
  bool open = false;

  @override
  Widget build(BuildContext context) {
// Never printed outside the first frame
    print('rebuild top');
    return GestureDetector(
        onTap: () {
          BottomWaveViewState waveViewState = BottomWaveView.of(context);
          open = !open;
          waveViewState.toogleWave(open);
        },
        child: const SizedBox(
          height: double.infinity,
          width: double.infinity,
          child: Placeholder(child: Center(child: Text('Has to resize'))),
        ));
  }
}

If you have some ideas, I would love to get your directions on this

RomanJos avatar Aug 28 '22 07:08 RomanJos