【问题标题】:Caching child widgets vs. recreating them缓存子小部件与重新创建它们
【发布时间】:2021-05-10 06:18:12
【问题描述】:

我不确定是否缓存小部件实例并在 build() 方法中重用它会产生重大影响。

假设我们有两个小部件类:

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
     */
  }
}

据我了解,每次 Flutter 在ParentWidget 上调用build() 时,都会创建一个新的ChildWidget 并将其附加到元素树中的同一个元素上。除非const ChildWidget 可用(例如ChildWidget 有一个 const 构造函数)。

但是,我们可以像这样缓存孩子:

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()
    );
  }
}

据我了解,将使用相同的小部件,并且不必通过颤振来修改元素树。但我不确定在哪些情况下重要。

缓存小部件和创建具有相同配置的新小部件之间是否存在显着差异? 如果是这样,是否有关于何时缓存小部件而不是重建它们的规则?

【问题讨论】:

    标签: flutter dart flutter-layout


    【解决方案1】:

    StatefulWidget的文档中,如果该widget所代表的子树没有改变,建议缓存该widget:

    如果子树没有改变,缓存代表该子树的小部件并在每次可以使用时重新使用它。与创建新的(但配置相同的)小部件相比,重用小部件效率大大提高。将有状态部分分解到一个接受子参数的小部件中是一种常见的方法。

    因此,我得出结论,每当 Widget 更改状态时,应缓存并重用不根据状态更改的子树。

    但是,问题中声明的示例并不是选择缓存小部件的好选择,因为只有不变子树的根应由该子树的父级缓存。但是由于ParentWidget 本身就是StatelessWidget,所以每次ChildWidget 都是一个不变的子树的一部分。因此,ParentWidget 的一些有状态的 Parent 应该负责缓存。

    【讨论】:

      【解决方案2】:

      可能会有所不同,例如,如果子小部件分配资源或具有较大的子子树。

      flutter api 官方文档确实建议在某些情况下进行缓存。但一般来说,在尝试优化视图时,它不应该是首先要做的事情。

      阅读有关StatefulStateless 小部件的文档,特别是“性能注意事项”部分有很多相关的进一步信息。例如:

      • 如果子树未更改,则缓存代表该子树的小部件,并在每次可以使用时重新使用它。
      • 尽可能使用 const 小部件。 (这相当于缓存一个小部件并重新使用它。)

      【讨论】:

      • 感谢您,我在StatefulWidget 的文档中找到了相关部分。他们建议在子树不更改时对其进行缓存,因为“与创建新的(但配置相同的)小部件相比,重用小部件的效率要高得多”。
      • 不过,在许多情况下,您可以通过其他方式优化渲染。我已经制作了 Flutter 应用程序,而无需缓存单个小部件。
      • 我同意。这个问题不是关于我在开发中遇到的具体问题,而是关于框架的工作原理。对我来说,“大大提高效率”也表明性能得到了很大的提升。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-02-12
      • 2023-03-09
      • 1970-01-01
      • 1970-01-01
      • 2014-11-15
      • 1970-01-01
      • 2023-02-15
      相关资源
      最近更新 更多