Flutter Stateful组件中build用.of(context)替代didChangeDependencies的性能问题
在StatefulWidget中把.of(context)方法放build里是否有性能问题?
大部分情况下,把MediaQuery.of(context)、Theme.of(context)、Provider.of(context)这类方法放在build方法里不会有明显的性能问题,但具体要分场景讨论:
核心原理:InheritedWidget的订阅机制
这类.of(context)方法本质是基于Flutter的InheritedWidget实现的——调用时会让当前Widget的Element订阅目标InheritedWidget的变化。不管你是在build还是didChangeDependencies里调用,订阅关系的建立逻辑是一样的:当依赖的InheritedWidget更新时,当前Widget都会触发rebuild。
而且Flutter内部做了缓存优化:第一次调用.of(context)时会遍历Element树找到目标InheritedWidget,之后结果会存在当前Element的缓存里,后续再调用同一个方法直接取缓存,不会重复遍历,所以单次或多次调用的性能开销都可以忽略。
什么时候需要考虑移到didChangeDependencies?
只有当你的.of(context)调用伴随非UI的 heavy 逻辑时,才需要放到didChangeDependencies里优化:
- 比如你用
Provider.of(context)获取数据后,要执行复杂计算、发起网络请求、初始化非UI变量等操作。如果把这些逻辑放在build里,每次build(哪怕是父Widget重建、setState触发的无关rebuild)都会重复执行,造成不必要的性能浪费。 - 而
didChangeDependencies只会在依赖的InheritedWidget真的发生变化时才会被调用,能避免上述重复执行的问题。
完全可以放心放build里的场景
如果只是用这些方法获取数据来构建UI(比如用MediaQuery的尺寸布局、用Theme的颜色设置TextStyle),直接放在build里完全没问题:
- build方法本身就是用来构建UI的,这些调用属于UI逻辑的一部分,性能开销微乎其微。
- 就算因为其他原因触发rebuild,这些简单的取值操作也不会对性能造成影响。
总结:不用过度纠结,UI相关的取值直接放build;伴随复杂非UI逻辑的依赖处理,再考虑移到didChangeDependencies。
内容的提问来源于stack exchange,提问作者ahmed arafat
相关产品推荐
相关产品推荐

