You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

StatefulWidget的build中声明Widget变量与直接实例化的性能差异?

关于Flutter组件重构写法的性能疑问

之前看到一种Flutter代码写法会因引发不必要的重构建影响性能,具体是在State类中把部分组件抽成类内方法:

class _MyStatefulWidgetState extends State<MyStatefulWidget> {
  int _counter = 0;

  Widget _buildNonsenseWidget() {
    return Container(
      child: Column(
        children: [
          Text('Hello'),
          Row(
            children: [
              Text('there'),
              Text('world!'),
            ],
          ),
        ],
      ),
    );
  }

  @override
  Widget build(BuildContext context) {
    return Row(
      children: [
        Text('Counter: $_counter'),
        _buildNonsenseWidget(),
      ],
    );
  }
}

现在想请教:如果采用下面这种先将组件实例赋值给变量再使用的写法,会不会产生同样的性能问题?还是和直接在children里实例化组件的写法性能一致?

写法一:先赋值给变量

class _MyStatefulWidgetState extends State<MyStatefulWidget> {
  int _counter = 0;

  @override
  Widget build(BuildContext context) {
    final dummy = DummyWidget();

    return Row(
      children: [
        Text('Counter: $_counter'),
        dummy,
      ],
    );
  }
}

写法二:直接实例化

class _MyStatefulWidgetState extends State<MyStatefulWidget> {
  int _counter = 0;

  @override
  Widget build(BuildContext context) {    
    return Row(
      children: [
        Text('Counter: $_counter'),
        DummyWidget(),
      ],
    );
  }
}

解答

这两种写法(先赋值变量和直接实例化)的性能表现完全一致,都不会出现那种抽成State类方法的写法带来的性能问题。

原因很明确:

  • 抽成State类方法的写法中,每次build执行时,_buildNonsenseWidget()都会重新生成一套全新的Container、Column、Text等Widget实例。即使这些组件的内容没有任何变化,Flutter的diff算法也会判定它们是新的Widget,从而触发整个子树的重构建。
  • 而使用独立Widget类(DummyWidget)的两种写法,不管是先赋值给变量还是直接写在children里,本质都是创建一个DummyWidget的实例。Flutter的diff算法会对比Widget的类型和key,只要DummyWidget自身的配置(比如传入的参数)没有变化,就不会触发它内部的build方法,只会复用原来的Element和RenderObject,避免不必要的重绘。

简单说,只要是用独立的Widget类来封装组件,不管是直接实例化还是先存变量,性能都是一样的,和那种在State里写_build方法的错误写法有本质区别。


内容的提问来源于stack exchange,提问作者anonymous-dev

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.08 19:13:23