JHHK

欢迎来到我的个人网站
行者常至 为者常成

Provider最佳实践️️

目录

应该怎么选

Consumer、Selector、Widget 拆分、const,应该怎么选择?当页面发生重建时,应该优先用哪种优化方式?

1、选择顺序

                需要监听数据?
                      │
                      ▼
             能拆 Widget 吗?
                │           │
              能           不能
              │             │
              ▼             ▼
       拆 Widget      使用 Consumer
              │
              ▼
       是否只关心部分字段?
              │
        ┌─────┴─────┐
        │           │
       否          是
        │           │
        ▼           ▼
      watch      Selector
      
      
最后如果Widget完全静态加:const。     

Consumer适合: 当前 Widget 自己不能 watch。比如AppBar的title更新

AppBar(
  title: ?
)

所以Consumer更多是: 无法拆 Widget 时的补救方案。
Selector适用于: 一个 Notifier 很大,但 Widget 只关心其中一个字段。
const不能阻止父 Widget build。 它优化的是:在updateChild方法中直接返回oldElement,根本不用调用canUpdateWidget。

2、企业项目中,我建议遵循的四条原则

Page 尽量不要 watch(),让最小业务 Widget 去 watch()。(就是watch不要放的太高)
先拆 Widget,再考虑 Consumer。
Consumer 放得越低越好,不要把整个页面包进去。
只有当一个 Notifier 很大,而 Widget 只关心其中一小部分数据时,再使用 Selector。

如果真正做到这四点,绝大多数 Provider 页面都能获得很好的性能,而代码结构也会更加清晰、易维护。

Notifier 应该如何拆分?(企业级架构)

一、企业经验

第一条
一个 Notifier 负责一个业务领域(Business Domain)。
不要负责整个页面。更不要负责整个App。

第二条
生命周期不同的数据,不要放进同一个 Notifier。
例如:Theme 整个 App。SearchKeyword 进入页面才有。

第三条
高频变化的数据,尽量独立。
例如:购物车数量,聊天未读数,股票行情这种每秒notify。不要跟用户信息放一起。

第四条
不要为了减少 Notifier 数量而合并业务。
其实恰恰相反。 Notifier拆得合理notify范围更小,性能反而更好。

二、架构图

App

│

├── Global Provider

│      │

│      ├── UserNotifier

│      ├── ThemeNotifier

│      ├── ConfigNotifier

│

├── Module Provider

│      │

│      ├── ShopNotifier

│      ├── OrderNotifier

│

└── Page Provider

       │

       ├── SearchNotifier

       ├── EditProfileNotifier

三、Notifier如何通讯

场景 推荐方案
一个页面同时操作多个 Provider UI 层协调
B 业务确实依赖 A 的数据 ChangeNotifierProxyProvider
大量模块需要响应全局事件 Event / Stream
  ChangeNotifierProxyProvider<UserNotifier, ChatProvider>(
    create: (_) => ChatProvider(),
    // 当 UserNotifier 数据改变时,update方法会被执行       
    update: (BuildContext context, UserNotifier user, ChatProvider? chat) {
      chat!.updateUser(user.id);
      return chat;
    },
  )

行者常至,为者常成!





R
Valine - A simple comment system based on Leancloud.