StatelessWidget vs a function returning Widgets in terms of performance

前端 未结 1 419
执念已碎
执念已碎 2021-02-05 11:26

Is there any difference, performance wise, in using a StatelessWidget vs a function returning a Widget?

I\'m well aware of at least the differ

相关标签:
1条回答
  • 2021-02-05 11:51

    First of all, I'd like to note that a package is available to make a StatelessWidget from a function: functional_widget


    The gain is performance is not necessarily true. It depends on how you use your widgets, mostly how you use them to manage your state.

    By default, classes may degrade performances when opposed to functions in an application that doesn't utilize their power.

    The real question is: What is their power?

    Simple: Classes can update independently from each other. Functions cannot

    It is possible for classes to partially update the widget tree.

    Consider a widget that rebuilds every frame and returns its child:

    class InfiniteLoop extends StatefulWidget {
      const InfiniteLoop({Key key, this.child}) : super(key: key);
      final Widget child;
      @override
      _InfiniteLoopState createState() => _InfiniteLoopState();
    }
    
    class _InfiniteLoopState extends State<InfiniteLoop> {
      @override
      Widget build(BuildContext context) {
        WidgetsBinding.instance.addPostFrameCallback((_) => setState(() {}));
    
        return widget.child;
      }
    }
    

    Now if we wrap our whole application in that widget, what happens?

    void main() => runApp(InfiniteLoop(child: MyApp()));
    

    Nothing

    Sure, you'll have one widget that rebuilds often in your tree. But in reality, the build method of MyApp will be called only once.

    That's because Flutter is able to abort the tree rebuild when the instance of a widget doesn't change.


    Classes can abuse of this optimization.

    Using classes it is possible to cleverly split the rebuilding of your widget tree into independent parts.

    It's not reasonable to list all the potential optimization factors that a class allow, as there are too many.

    The following example is a widget that takes an int and formats it into a Text. The catch is, this widget will rebuild only if the int passed change:

    class Counter extends StatelessWidget {
      const Counter({Key key, this.value}) : super(key: key);
    
      final int value;
    
      @override
      Widget build(BuildContext context) {
        return Text(value.toString());
      }
    
      @override
      bool operator ==(Object other) =>
          identical(this, other) || (other is Counter && other.value == value);
    
      @override
      int get hashCode => value.hashCode;
    }
    

    This works because Flutter uses the == operator to know if a widget should update or not (hence why const constructor is a good optimization factor).

    This is not the only solution, but it's a good example of something that functions can't do.

    0 讨论(0)
提交回复
热议问题