Flutter如何重建变更子树?其更新算法的执行逻辑是怎样的?
Flutter 子树更新算法核心机制
Flutter的更新逻辑运行在Element树层,Widget本身是不可变的配置描述,Element才是持有状态、负责维护树结构、执行更新的实体。标记为dirty的子树根节点会在下一帧进入build流程,核心逻辑围绕updateChild(单子组件)/updateChildren(多子组件)展开,核心规则如下:
- 节点复用判断:对新旧两个Widget,先对比
runtimeType和key,二者完全一致时不会销毁旧Element,只会将新Widget配置挂载到旧Element上,再触发该Element的更新;二者任一不匹配时会直接销毁旧Element及它的整棵子树,根据新Widget创建全新的Element挂载。 - 多子节点匹配:Column、Row这类承载多个子组件的Element,调用
updateChildren时会优先按同位置、同key、同类型的规则匹配可复用的子Element,处理完节点的新增、删除、位移后,再逐个触发匹配到的可复用子节点的更新。 - 遍历规则:整个更新流程是深度优先的前序遍历,处理某个节点时,会先更新节点自身,再按顺序逐个处理它的子节点,必须等前一个子节点的整棵子树全部更新完成,才会开始处理下一个同层兄弟节点。
示例场景的更新顺序
针对Column包含w1、w2,二者分别包含子组件w1-1、w2-1的场景,更新从Column对应的Element节点启动,完整顺序为:
- Column节点执行自身rebuild,生成新的子Widget配置列表
- Column调用
updateChildren匹配到旧的w1、w2对应的Element均可复用,优先处理第一个子节点w1对应的Element - 触发w1节点的rebuild,w1生成自己的子Widget配置(新w1-1),调用
updateChild匹配到旧w1-1对应的Element可复用 - 触发w1-1节点的rebuild,如果w1-1没有更多子节点,完成自身更新后逐层返回,w1整棵子树更新完毕
- 回到Column的子节点遍历流程,开始处理第二个子节点w2对应的Element
- 触发w2节点的rebuild,w2生成自己的子Widget配置(新w2-1),调用
updateChild匹配到旧w2-1对应的Element可复用 - 触发w2-1节点的rebuild,如果w2-1没有更多子节点,完成自身更新后逐层返回,w2整棵子树更新完毕
- Column所有子节点处理完成,整棵变更子树的更新流程结束
注:w1-1的更新时机早于w2节点本身,更早于w2-1,不存在同层子节点先全部更新再处理下层的逻辑。
算法实现与说明查阅渠道
不需要跳转外部站点,直接在本地拉取的Flutter源码中即可查阅完整实现与官方注释:
- 核心逻辑位于
packages/flutter/lib/src/widgets/framework.dart文件中,Element类的updateChild方法、rebuild方法、performRebuild方法是单节点更新的核心入口;MultiChildRenderObjectElement类的updateChildren方法是多子节点Diff更新的核心实现。 - 源码中每个核心方法都附带了框架开发者写的详细注释,说明设计逻辑、边界处理规则,是最权威的参考资料。
内容的提问来源于stack exchange,提问作者May
相关产品推荐
相关产品推荐

