對于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:
```
class ModelNotifier extends ChangeNotifier {
var text;
var chartData1;
var chartData2;
var list;
updateText(newText) {
text = newText ;
notifyListeners();
}
...省略其餘更新函數...
// 獲取遠程數據源
getRemoteData() {}
}
ps: 僞代碼
```
這是一個簡單的頁面級的例子:
```
... 省略非關鍵代碼
return ChangeNotifierProvider(
create: (context) => CartModel(),
child: const RootWidget(
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機制用法,其次就是 針對接口的調整,在龐大的數據集合中,合理地拆分接口數據可以減少對流量的浪費.也可以讓用戶體驗更上一個台階.
,更多精彩资讯请关注tft每日頭條,我们将持续为您更新最新资讯!