Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Caching child widgets vs. recreating them

Im unsure about wether caching a widget instance and reusing it in the build() method makes a significant difference.

Suppose we have two widget classes:

class ParentWidget extends StatelessWidget {
  ParentWidget({Key key})
      : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Container( // or some other widgets that define the ui
      child: ChildWidget(/*...*/),
    );
  }
}

class ChildWidget extends StatelessWidget {
  ChildWidget({Key key}) : super(key: key); // no constant

  @override
  Widget build(BuildContext context) {
    /*
     * returns some Widget
     */
  }
}

From my understanding, everytime Flutter calls build() on the ParentWidget, a new ChildWidget is created and attached to the same Element in the element tree. Except if const ChildWidget is available (e.g. ChildWidget has a const constructor).

However, we can cache the child like so:

class ParentWidget extends StatelessWidget {
  final Widget child;
  ParentWidget({Key key})
      : child = ChildWidget(/*...*/),
        super(key: key);

  @override
  Widget build(BuildContext context) {
    return Container(
      // or some other widgets that define the ui
      child: child, // <-- use child instead of ChildWidget()
    );
  }
}

From my understanding, the same widget will be used and no modification of the element tree has to be done by flutter. But I am unsure in which cases that matters.

Is there a significant difference between caching a widget and creating a new Widget with the same configuration? If so, is there a rule on when to cache widgets instead of reconstructing them?

like image 262
Tobias Braun Avatar asked Feb 05 '21 22:02

Tobias Braun


People also ask

When should I use stateful widgets?

Stateful widgets are useful when the part of the user interface you are describing can change dynamically, e.g. due to having an internal clock-driven state, or depending on some system state.

How do you rebuild a stateful widget in Flutter?

Using setState to rebuild widgets Flutter gives you access to setState() . In this case, we have to ensure setState() has the new values. When setState() is called, Flutter will know to get these new values and mark the widget that needs to be rebuilt.

Which method of stateful widget notifies the changes in UI?

A stateful widget is implemented by two classes: a subclass of StatefulWidget and a subclass of State . The state class contains the widget's mutable state and the widget's build() method. When the widget's state changes, the state object calls setState() , telling the framework to redraw the widget.

How do I create a stateful widget?

To create a stateful widget in a flutter, use the createState() method. The stateful widget is the widget that describes part of a user interface by building a constellation of other widgets that represent a user interface more concretely. A stateful Widget means a widget that has a mutable state.


2 Answers

In the documentation of StatefulWidget, it is recommended to cache a widget if the subtree represented by that widget does not change:

If a subtree does not change, cache the widget that represents that subtree and re-use it each time it can be used. It is massively more efficient for a widget to be re-used than for a new (but identically-configured) widget to be created. Factoring out the stateful part into a widget that takes a child argument is a common way of doing this.

I therefore conclude that whenever a Widget changes State, subtrees that do not change based on the state should be cached and reused.

However, the example declared in the question is not a situation in which choosing to cache the widget is a good option, as only the root of a not-changing subtree should be cached by the parent of that subtree. But as ParentWidget is itself a StatelessWidget, it will be part of a not-changing subtree each time ChildWidget is. Therefore, some stateful Parent of ParentWidget should be responsible for caching.

like image 177
Tobias Braun Avatar answered Oct 19 '22 01:10

Tobias Braun


There can be a difference, if for example the child widget allocates resources or has a large subtree of children.

The official flutter api documentation does recommend caching in certain situations. But generally, it should not be the first thing to do, when trying to optimise your views.

Read the documentation on Stateful and Stateless widgets, in particular the "Performance Considerations" section has a lot of relevant further information. For example:

  • If a subtree does not change, cache the widget that represents that subtree and re-use it each time it can be used.
  • Use const widgets where possible. (This is equivalent to caching a widget and re-using it.)
like image 34
Kristian Avatar answered Oct 19 '22 00:10

Kristian