Appearance
flutter-three-trees
1. 实验目标
用 debugDumpApp / debugDumpRenderTree 观察 Flutter 的「三棵树」与 Layer 生成(对应 docs/07-performance-testing-debug/11):
- Widget 树:配置描述(不可变、可频繁重建)
- Element 树:Widget 的实例化管理(复用/重建决策)
- RenderObject 树:真正的布局/绘制(含
Layer) - 对比加
const前后、RepaintBoundary前后,rebuild 范围与 Layer 数量的变化
本实验给出观测代码与命令(见「7. 关键源码」);以独立 Dart 片段形式给出,暂不并入 Flutter Host 的
lib构建,避免影响宿主编译。
2. 工程要点
const构造函数:Widget 相同配置时跳过重建(Element 复用),是性价比最高的优化RepaintBoundary:在 RenderObject 树插入新的OffsetLayer,把重绘隔离在子树内,避免整树重绘debugDumpApp()打印 Widget/Element 树;debugDumpRenderTree()打印 RenderObject/Layer 树;DevTools 的 「Performance Overlay / Layer」更直观
3. 运行方式
dart
// 在 build 里临时调用(debug 模式)
import 'package:flutter/rendering.dart';
void inspectTrees() {
debugDumpApp(); // Widget + Element 树
debugDumpRenderTree(); // RenderObject + Layer 树
}bash
# 或 DevTools → Performance → 勾选 "Show UI guides / Highlight repaints"
flutter pub global activate devtools
flutter devtools4. 预期现象
- 未加
const:父 Widget 重建时,子树 Widget 全部重建(Element 重新创建) - 加
const:子树 Element 复用,rebuild 计数不变 - 包裹
RepaintBoundary后:该子树拥有独立Layer,父层重绘不再牵连它(Layers 数 +1,但重绘范围变小)
5. 常见误区
| 误区 | 实际情况 |
|---|---|
| 所有 Widget 加 const 一定更快 | 过度 const 增加内存常驻,应按「配置稳定」按需使用 |
| RepaintBoundary 越多越好 | 每个 boundary 增一个 Layer,过多反而增合成开销 |
| 看 build 次数 = 看绘制开销 | build 是 Widget 重建,绘制是 RenderObject,两者解耦,要分别看 |
6. 对应知识库文档
- 理论主文档:Flutter 三棵树与 Layer Tree:Widget / Element / RenderObject / Layer
- 相邻专题:Flutter Impeller 渲染引擎架构与 Shader 编译卡顿消除原理
7. 关键源码
dart
// 对照:const 前后的 rebuild 范围
class Counter extends StatelessWidget {
const Counter({super.key}); // const 构造:配置相同时跳过重建
@override
Widget build(BuildContext context) {
return RepaintBoundary( // 隔离重绘子树
child: Text('hello', style: Theme.of(context).textTheme.bodyLarge),
);
}
}接入状态
✅ 已接入 Flutter 宿主 App:对应 ThreeTreesDemoPage,从主页 → 「Flutter 三棵树 / Layer Tree」进入。上面的 const 优化、RepaintBoundary、debugDumpApp/RenderTree 演示均在该页面内交互运行。