对于Flutter开发的工程师们,肯定是对Provider很熟悉。 这个是官方推荐的一个状态管理插件。对于Flutter应用Provider的出现是提高App性能一剂良药,也是管理状态的良好工具,可是Provider真的就是一个没有副作用的状态管理利器吗?非也!甚至他会毁掉你的App! 完全无必要的无脑使用 首先我们以一个widgets树为例来解说: 图例说明: 上图中我们Widgets分别是一个Root视图;还有4个子Widgets,分别是: Text Chart1 Chart2 ListView 子Widgets它们分别对应数据源是: text chartData1 chartData2 list 现在清楚我们的Widgets树层级结构和数据来源,我们开始使用Provider来进行状态管理;首先我们应该在根Widget中设置ChangeNotifierProvider用来包裹数据源和组件视图;然后创建ChangeNotifier关联数据和变化通知;最后子视图就可以跨层级使用ChangeNotifierProvider包裹的数据源。简单说明一下代码逻辑:我们来看一下例子: 构建一个ChangeNotifier:classModelNotifierextendsChangeNotifier{varchartData1;varchartData2;updateText(newText){textnewTnotifyListeners();}。。。省略其余更新函数。。。获取远程数据源getRemoteData(){}}ps:伪代码 这是一个简单的页面级的例子:。。。省略非关键代码returnChangeNotifierProvider(create:(context)CartModel(),child:constRootWidget(Consumer(Text(text)),Collection(Consumer(Chart1(chartData1)),Consumer(Chart2(chartData2)),),Consumer(ListView(list)),),)。。。省略非关键代码ps:伪代码 以上我们将伪代码也粘贴了出来,现在我们来演示一下数据从远程过来之后,Provider更新数据状态进而更新UI的流程。 首先,假设这是一个接口返回回来的数据,这个时候我们将一并获取:text、chartData1、chartData2、list的数据,那么我们想要更新4个子Widget就必须分别调用updateText以及其他的更新视图的函数,并传递从接口获取到新的数据;这个时候我们就会发现,Provider的使用就变的没有任何意义,甚至拖沓了更新UI的时间,我们完全可以不使用Provider处理数据,完全可以在根视图中采用setStates函数来刷新整个层级树,以为此时的Provider做的事情也是刷新整个层级树视图。所以分析可以知道有几个不合理的点:一个接口就获取到所有数据更新数据源的时候没有判断数据的更新内容 改良 我们就针对两个问题进行处理,第一我们分别对接口进行拆分若干: 1。获取Text内容 2。获取两个Charts的内容 3。获取ListView的内容 这样我们可以在获取某些数据的时候对部分组件进行更新,且在同一时间减少了整体渲染带来的大量性能损耗。 其次,对新数据的检查也是有必要的额,首先我们要增加数据新旧检验的机制,在通过检验,新数据符合渲染条件,就通知更新,否则就放弃本次的更新,这样也在一定程度上减少渲染次数。 总结 Provider的合理使用是提高整体性能的保证,我们在很多的静态数据面前,其实是没有使用Provider的必要的,甚至在一些只是更新数据而不涉及UI更新的地方也需要使用注意使用Provider的非更新UI机制用法,其次就是针对接口的调整,在庞大的数据集合中,合理地拆分接口数据可以减少对流量的浪费。也可以让用户体验更上一个台阶。