一、核心区别
- StatelessWidget(无状态组件) :页面数据不会变,渲染一次就不动了,没有可变状态。
- StatefulWidget(有状态组件) :页面数据会变(点击按钮、输入文字、记计器等),拥有可变状态,能刷新 UI。
二、详细对比
表格
| 特性 | StatelessWidget | StatefulWidget |
|---|---|---|
| 是否有状态 | ❌ 无 | ✅ 有(存放在 State 里) |
| 能否刷新 UI | ❌ 不能(数据写死后无法修改) | ✅ 能(调用 setState() 刷新) |
| 生命周期 | 简单(仅构建) | 复杂(创建→更新→销毁) |
| 性能 | 更高(无刷新开销) | 稍低(有状态管理) |
| 结构 | 一个类,直接实现 build | 两个类:Widget + State |
| 使用难度 | 简单 | 稍复杂 |
三、怎么选择用哪个?
用 StatelessWidget 的场景(静态展示)
只要页面内容不会主动变化,一律用它!(性能最好)
- 纯文本、图标、静态图片
- 标题栏、分割线、静态卡片
- 不需要交互、不需要修改数据的 UI
- 列表里的静态 item
例子:登录页标题、APP 图标、固定文案、静态底部导航。
用 StatefulWidget 的场景(动态交互)
只要页面会变、会交互,必须用它!
- 点击按钮改变文字 / 颜色 / 显示隐藏
- 输入框、表单、勾选框、开关
- 倒计时、轮播图、下拉刷新
- 网络请求后更新页面
- 视频 / 音乐播放界面
例子:计时器、登录页输入框、列表刷新、设置页开关。
四、性能区分原理
4-1、核心结论
StatelessWidget ≈ 一次性渲染,几乎无额外开销
StatefulWidget ≈ 带状态管理 + 可触发重建,有额外开销
性能差距的本质来自以下几点:
- 结构复杂度
- 重建(rebuild)机制
- setState () 带来的连锁刷新
4-2、底层原理:两者的结构区别
1. StatelessWidget 结构
StatelessWidget
↓
build() 【只执行一次,除非父组件刷新】
- 没有状态对象
- 没有 State 类
- 没有生命周期监听
- 内存占用更小
2. StatefulWidget 结构
StatefulWidget ← 本身不可变
↓
创建 State 对象 ← 【多出来的一层】
↓
State 持有状态、生命周期、setState
多出来的东西:
- State 实例(内存)
- 生命周期钩子(initState、dispose、didUpdateWidget...)
- 状态监听与刷新机制
- 框架需要跟踪管理它
这是第一层性能开销:结构更重。
4-3、最关键:重建(Rebuild)机制不同
✅ Stateless 的重建规则
- 自己不能主动刷新自己
- 只有父组件刷新时,它才会跟着重建
- 重建成本极低:只是重新执行 build ()
❌ Stateful 的重建规则
- 自己可以主动刷新自己 →
setState() - 一旦调用
setState→ 整个子树都会重建 - 即使数据没变,也会触发重建
举个例子:
setState(() {
_count++;
});
这行代码会让:
- 当前 State 标记为dirty
- 整个 build () 方法重新执行
- 页面里所有子组件全部重新构建
这是Stateful 性能不如 Stateless 的核心原因。
4-4、内存与垃圾回收原理
Stateless
- 组件是 immutable(不可变)
- 无额外对象,无监听
- 销毁时直接回收,无残留
Stateful
- Widget + State 两个对象
- State 会持有上下文、状态、订阅
- 销毁时需要解绑、释放、回收
- 更容易产生内存滞留
4-5、最直白的性能对比
表格
| 行为 | StatelessWidget | StatefulWidget |
|---|---|---|
| 自身能否刷新 | ❌ 不能 | ✅ 能(setState) |
| 重建频率 | 低 | 高 |
| 内存占用 | 小 | 大 |
| 框架监听 | 无 | 有 |
| 生命周期 | 无 | 完整 |
| 重建消耗 | 极低 | 高(子树全部重绘) |
五、为什么官方强烈推荐:能用 Stateless 就不用 Stateful?
因为:
1. Stateful 会带来不必要的重建
你只想改一个数字 → 结果整个页面都重建了。
2. Stateful 更容易写出性能差的代码
新手最容易犯的错:
- 整个页面用一个巨大 Stateful
- 随便点个按钮就调用 setState
- 页面一复杂就卡顿
3. Stateless 更简单、更稳定、框架优化更好
六、总结底层原理
Stateless 性能高的原因:
无状态、无管理、不可变、不主动刷新、重建成本极低。
Stateful 性能相对低的原因
带状态、带生命周期、可主动调用 setState 重建整个子树,内存与调度开销更大。
页面内容永远不变 → Stateless(最快)
页面内容会变/会交互 → Stateful(必须用)
最终总结
- Stateless:轻量、无状态、不主动刷新 → 性能最高
- Stateful:重量、带状态、可 setState 刷新 → 性能稍低
- 差距来源:重建机制 + 结构复杂度 + 状态管理开销
- 最佳实践:组件最小化 + 能无状态则无状态