天天看點

Redux/Mobx/Akita/Vuex對比 - 選擇更适合低代碼場景的狀态管理方案

近期準備開發一個資料分析 SDK,定位是作為資料中台向外輸出資料分析能力的載體,前端的功能表現類似低代碼平台的各種拖拉拽。作為中台能力的載體,SDK 未來很大機率會需要支援多種視圖層架構,比如Vue2/Vue3/React等。是以在技術架構上對視圖層架構的依賴性越輕,疊代的成本越低。基于這樣的目标,本文對前端狀态管理工具進行調研,在技術選型上應當盡量減輕與視圖架構的綁定程度,理想的目标是建構與視圖架構無關的資料/狀态管理層。

調研對象包括以下:

調研對象 說明
Redux 最早的基于Flux架構改進的狀态管理工具,生态繁榮,有豐富的中間件和插件滿足不同場景需求,較多搭配React
Vuex Vue專用的狀态管理工具,與 Redux 同屬 Flux 體系
Mobx 基于響應式程式設計思想,近兩年成長為React社群最流行的狀态管理工具之一
Akita 基于RxJS的響應式狀态管理工具
RxJS RxJS并不是狀态管理工具,但其響應式的設計有很大想象空間

RxJS 跟狀态管理沒有任何關系,不過它天生适合編寫異步和基于事件的程式,有了這個前提,完全可以封裝一套基于 RxJS 的狀态管理架構,比如 Akita。同時RxJS 非常适合用來管理事件流,如果狀态管理工具能夠與 RxJS 比較好的搭配使用,能夠達到事半功倍的效果。本文的調研不涉及 RxJS,此處隻列舉出它的作用,不做細節調研。

通過以下幾個次元進行對比(排名分先後):

對比次元
業務場景覆寫率 工具本身搭配社群解決方案是否能夠覆寫業務場景所需的能力
資料流 了解每個工具的資料流模式是所有調研的基礎
與視圖架構的綁定程度和改造成本 大部分狀态管理工具都可以相容多種視圖架構,但一般需要适當的改造以提高開發便利性
風險和隐患 開源工具的選型都有一定隐患,主要考慮社群、生态以及開發團隊響應的及時性
性能 資料分析場景需要處理的資料量很大,對工具有一定性能要求,不過工具本身的性能遠未達到能夠成為應用的瓶頸的程度,是以此項僅作參考
學習曲線 結合目前研發人員的技術能力衡量上手成本和學習曲線,鑒于有一定的技術儲備時間,此次元的占比可以适當放低
資料分析SDK是純端側的産品,是以本文調研的幾個工具對于SSR的支援不在調研範圍之内。

在進入調研之前,首先把資料分析 SDK (下文簡稱分析 SDK)的定位以及業務場景講清楚。

分析 SDK 是資料分析功能的承擔者,但 SDK本身不是一個可用的完整産品,上層需要一個分析平台作為宿主載體。以網易有數為例,網易有數是一個大資料平台,它包含很多功能,比如看闆、報告定制、取數、多元分析等等。分析 SDK 在其中的角色就是這些功能的載體,網易有數平台将分析 SDK 內建進來,以可視化的形式提供分析相關的功能。下圖展示的是網易有數報告定制的頁面:

Redux/Mobx/Akita/Vuex對比 - 選擇更适合低代碼場景的狀态管理方案

資料分析是一種類似的低代碼的業務場景,從技術角度上有以下特征:

  • 資料量大且結構複雜;
  • 事件流複雜、高頻且時序敏感;
  • 元件結構複雜且互相之間存在大量的資料共享。

除此之外,之是以要做一個分析 SDK而不是分析平台,是因為中台的服務産出需要支援前台業務的接入,分析 SDK 的目标使用者是前台業務部門的各個分析平台。在這個前提下,分析 SDK 對技術有另外一個額外要求:

  • 支援前台分析平台的技術棧。

而前台不止一個,不同業務線的技術棧也不統一,前端技術棧的契合度主要是元件要支援多種視圖層架構,比如React、Vue2、Vue3甚至Angular,是以分析 SDK的技術架構應當盡量減輕對視圖層架構的依賴程度,将核心業務邏輯從視圖層抽離出來。這樣的好處能夠降低支援不同視圖層架構時所投入的人力成本、時間成本和維護成本。這就是本文開頭所說的為什麼要建構與視圖架構無關的資料/狀态管理層的原因。「Smart Modeling,Dumb View」,即邏輯集中在資料層,視圖層盡量隻做展示(類似 React 的 Pure Component)。

結合分析 SDK的定位和業務場景,可以提煉出對狀态管理工具的幾點具體需求:

  • 支援 state 按子子產品劃分命名空間,以便支援複雜資料模型;
  • 與視圖層架構沒有強綁定關系,以便支援多種視圖層架構;
  • 支援時間回溯,比如undo/redo,這是編輯器的基本操作。

目前絕大多數狀态管理工具都遵循單向資料流原則,這項原則最早是由 Flux 帶入到前端領域,是以在了解各個狀态管理工具的資料流之前,有必要先搞清楚 Flux 架構。

這部分隻考慮正常互動場景下的資料流向,也就是隻考慮由view層觸發資料變動的情況,不考慮單元測試等非正常互動場景。

Flux

Redux/Mobx/Akita/Vuex對比 - 選擇更适合低代碼場景的狀态管理方案
  • Action是描述一個行為的對象,每個 action 裡都包含兩部分資訊:actionType 和 payload,分别代表行為的類型和攜帶的資料;
  • Dispatcher是一個排程中心,它是 action 和 store 的連接配接中心。有兩個核心方法:
    • dispatch

      方法:觸發一個 action,一般由 view 層調用;
    • register

      方法:用于注冊 actionType 的回調,在回調中操作 store。
  • Store是資料倉庫以及資料操作的唯一場所,當資料發生變化時,向外廣播

    change

    事件;
  • View層監聽 store 的

    change

    事件,調用

    setState

    方法來更新相應的元件狀态。

Flux 并沒有規定如何進行異步操作,比如接口的網絡請求,這種場景在前端應用中非常高頻。為了解決這種問題,有人提出了Action Creators的概念并在開發者社群獲得了認同,加入 Action Creator 之後的 Flux 資料流如下:

Redux/Mobx/Akita/Vuex對比 - 選擇更适合低代碼場景的狀态管理方案

Action Creators 顧名思義就是 action 的「制造者」,在“制造”action之前可以進行任何行為,包括異步操作。比如以下代碼:

async function updateUserInfoCreator(){
 // 第一步:異步擷取使用者資訊
  const info = awaitfetch('...');
  //第二步:觸發action
  dispatch({
actionType: 'UPDATE_USERINFO',
    data: info
  });
}
           

在 view 層調用

updateUserInfoCreator

函數即可。

Flux 的價值更多的展現在理論而非實用意義上,它提出的單向資料流模式被後續很多優秀的狀态管理工具借鑒。Facebook 提供了一個 Flux 實作,不過目前很少有開發者直接使用它,而是使用一些在 Flux 架構模式基礎上的改進方案,最廣泛的就是 Redux。

Redux 遵循 Flux 的單向資料流思想,與 Flux 不同的是,Redux 沒有 Dispatcher 的概念,而是将本屬于 Dispatcher 的

dispatch

方法内聚到了 Store 對象上。

Redux/Mobx/Akita/Vuex對比 - 選擇更适合低代碼場景的狀态管理方案
  • Redux 中 Action 的定位與 Flux 一緻,都是描述一個具體行為的對象,包括 actionType 和 payload 兩部分資訊;
  • Redux 中的 Store 隻有一個,也就是單一資料源,并且所有 state 共同組成了一個樹形結構。這與 Flux 不同,Flux 并沒有規定 Store 的個數限制以及 state 的組合方式,可以一個 store 對應所有 view,也可以每個 view 分别對應一個 store;
  • Reducer 是 Redux 的專有概念,響應 action 并傳回更新後的 state 發送到 store 中。Reducer 并不會修改 state,而是在 action 和 old state 基礎上計算出新的 state 值并發送給store,沒有任何副作用,更新 state 的行為是由 store 内部進行,對開發者不可見。

與 Flux 一樣,Redux 同樣沒有規定如何處理異步資料流。最原始的方案是上文提到的 Action Creators。不過 Redux提供了更優雅的解決方案:中間件。

關于 Redux 中間件的詳細使用方案就不介紹了,熟悉 Node.js 的開發者更容易了解中間件的概念,Express、Koa都實作了這種模式。

Redux 中間件同時也擴充了

dispatch

的行為,隻要保證經過多個中間件的一系列連續行為的最後

dispatch

傳回一個規範的 action對象即可,中間過程中可以

dispatch

一個 action creator 函數,這個函數内部還可以再次

dispatch

另一個 action。

中間件極大的豐富了 Redux 的可擴充性,孵化出很多優秀的異步資料流解決方案,比如 redux-thunk、redux-saga 等等。

綜合以上,Redux 的優勢有以下幾點:

  • 單向資料流;
  • 單一資料源,state聚合友善支援時間回溯;
  • 引入資料不可變性理念( Reducer 本質是一個純函數),state 寫行為收斂;
  • 可擴充性高。

Redux 同時也有一些被人诟病的缺點,主要有兩個:

  • 繁瑣。各個角色配置設定的很精細,這樣的優點是行為單一邏輯嚴謹,缺點是樣闆代碼(boilerplate code)數量大,尤其是 reducer,在複雜場景中需要寫大量的switch,可讀性差維護難度大,要了解一個狀态機往往需要配合好幾個代碼檔案才能讀懂;
    樣闆代碼指的是為了完成一個功能所需的所有代碼。
  • 複雜。Redux 預設隻支援同步資料流,提供中間件機制讓開發者自己定制異步資料流,社群中的解決方案複雜度不一,複雜業務場景下的解決方案比如 redux-saga 的複雜度更是高出幾個量級,導緻開發者在做技術選型和寫代碼時很頭疼。
    在複雜度方面,Redux 跟前端這個行業很像,看上去非常簡單,稍一深入就卧了個槽。

另外,Redux 是函數式程式設計的推崇者,架構和API 設計對喜歡函數式程式設計的開發者非常友好。

Vuex 是針對 Vue 的一種特異化的 Flux,保留了單向資料流的核心概念,同時吸取了部分 Redux 的理念。跟 Flux/Redux相比,Vuex 是更加全面的狀态管了解決方案,提供了異步操作支援,見下圖:

Redux/Mobx/Akita/Vuex對比 - 選擇更适合低代碼場景的狀态管理方案

由于 Vuex隻能搭配 Vue 使用,不具備适配多種視圖架構的能力,是以詳細的解析就不寫了,隻簡單提一下它的優缺點。

Vuex的優點在于:

  • 全面。Vuex 天然支援異步資料流,開發者不必操心選型問題。當然這個也有兩面性,如果存在 Vuex 覆寫不了的業務場景(雖然機率很小),那麼很大可能造成包括視圖層技術棧的整體遷移;
  • 易用。包括兩方面,一是 API足夠簡單,

    $store

    對象直接挂載到 Vue 執行個體對象上;二是各角色劃厘清晰且職責單一( action 相對複雜一些),容易了解;
  • 響應式。與 Vue 的響應式特性天然結合,配合簡單易用的 API,Vue + Vuex 的組合在寫代碼時非常舒服。
這裡額外說一點,Vue 與 React實作響應式的方式不一樣,React 是通過事件 push 機制實作,Vue 是借助 Proxy 進行 IO 劫持實作。

Vuex 的缺點,僅個人了解,有以下幾點:

  • 适用面窄。與 Vue 強綁定,不适用于其他視圖架構。當然這也是跟它自身的定位有關,Vuex 本來就是針對 Vue 的解決方案,并沒有想成為一種通用方案。這算不上缺點,但在資料分析 SDK這個需求背景下确實不合适;
  • 繁瑣。與 Redux 一樣,樣闆代碼過多造成閱讀代碼的難度加強。

Vuex 和 Redux 本質上都是基于 Flux 的改進方案,核心思想同屬于 Flux 體系。接下來幾個是另外一套體系:響應式。

Mobx 是一個基于函數式響應式程式設計(Functional Reactive Programming,簡稱 FRP)的狀态管了解決方案,同樣遵循單向資料流原則。

Redux/Mobx/Akita/Vuex對比 - 選擇更适合低代碼場景的狀态管理方案

了解 Mobx 之前,必須先搞清楚兩個核心概念:

observable

observer

。從名字上很好了解,

observable

是可被觀察的對象,

observer

是觀察者。這兩個概念被廣泛地使用在釋出訂閱模式(Pub/Sub Pattern)、觀察者模式(Observer Pattern)以及響應式程式設計中。

observable

對象的變化會“自動觸發”

observer

對象執行對應的響應邏輯,而自動觸發的實作方式在不同的工具中存在差異,進而造成代碼範式、擴充性、性能等方面的差異。

在此背景之下,再去了解Mobx中的三個核心概念:

  • State - 狀态,顧名思義就是應用程式使用的狀态資料,在 Mobx 中,state 是一種 Observable 對象;
  • Actions - 動作,是任何一段可以改變 state 的代碼。Mobx中的 action 與 Redux 和 Vuex 中的 action 都不同,Redux 的action 是行為的描述對象,并不會改變 state;Vuex 中的 action 是可選的,一般是用來執行異步操作,而改變 state 的執行者是 mutation。Mobx 中 action 其實是一個抽象概念,action 的目的是修改 state,至于如何修改完全交給開發者自由發揮,也就是說 action 中可以包含任意邏輯的代碼,包括異步操作(action.bound/runInAction/flow);
  • Derivations - 衍生。Mobx 官方對 derivation 的定義如下:
    Redux/Mobx/Akita/Vuex對比 - 選擇更适合低代碼場景的狀态管理方案

    有些不好了解,其實可以簡單粗暴的把 derivation 了解成 Observer 對象,它對 state 的改變做出響應,但是有一個條件,derivation隻能消費 state,不能對 state 進行再次操作。

    Derivation 分成兩種:

    • Computed values - 計算值,類似 Vue 中的 computed value,基于 state 使用一個純函數計算出另外一個值;
    • Reactions -反應,根據 state 改變自動觸發的一些副作用,比如渲染 UI。
    至于什麼時候用 Computed 什麼時候用 Reaction 其實并沒有絕對的邊界,Reaction 可以解決絕大多數問題隻不過需要自己寫代碼模拟 Computed(這一點也跟 Vue 中的 watch 和 computed 類似),如果應用中需要一個基于 state 的派生值同時這個值有一定的複用性,可以考慮使用 Computed。

Mobx的優點是,它沒有 Redux 和 Vuex 中那麼多概念,樣闆代碼的數量很小,代碼可讀性和可維護性高。基于這一點,Mobx 的上手也非常容易,開發者需要了解的概念越少越容易上手。此外,雖然 Mobx 是基于 FRP,但它的 API設計非常适合面向對象程式設計,比如 decorator 裝飾詞、class 是一等公民等等。而且有 Reactions 作為響應式程式設計和指令式程式設計的橋梁,開發者可以用更舒服的範式寫代碼。

decorator 還沒有成為 JavaScript 語言标準(ES)的一部分,Mobx 6中移除了 decorator 裝飾器文法,不過核心思想沒有改變。之是以移除 decorator,一方面是為了向 JavaScript 語言标準靠攏,另一方面是由于 decorator本身的代碼量很大,增大了打包後的 js 檔案體積。

Mobx 雖然不是 Flux 系列,但有一點與 Flux 的設計理念相同:沒有規範 store 的組織模式。Redux 和 Vuex 中的 store 都是樹形結構,單一資料源并且友善快照(snapshot),這個優點讓兩者非常便于調試,并且支援時間回溯的場景上遊刃有餘。而 Mobx 并沒有這些優點,是以社群中湧現了一批補充方案,比如mobx-state-tree(簡稱MST)和mobx-keystone,核心思想就是将 store 的組織結構聚攏為樹狀,以便支援更友好的調試和時間回溯。

綜合以上,總結 Mobx的優點是:

  • 簡單易學習;
  • 代碼可讀性和可維護性高;
  • OOP編碼範式,易于上手。

缺點有以下:

  • 調試困難(與Redux/Vuex相比);
  • 不支援時間回溯。

搭配使用一些社群解決方案,Mobx的以上缺點可以得到一定程度上的彌補。

有很多開發者認為 Redux更适合複雜的大型應用,Mobx 适合資料流相對簡單的應用。這其實并不絕對。Redux 嚴謹的代碼組織确實對複雜場景有加分,但 Mobx 也并不是不适用,而且市場中已經有很多 Mobx 解決複雜場景的實踐經驗,比如低代碼開發平台Mendix,而且 Mendix 的業務場景與資料分析有很高的相似度,這也從側面證明了 Mobx 與此類低代碼場景的契合度。

Akita是來自 Datorama 公司研發團隊的前端狀态管理方案,跟其他幾個競品相比,Akita 的資曆是最淺的。不過 Akita有一個優勢:與 Mobx一樣,Akita 經過了與資料分析類似業務場景的實踐驗證。Datorama 是一家提供資料解決方案的公司,它的業務場景與資料分析有很大的重合度,Akita 已經在 Datorama 的一些産品中得到了實踐和驗證。

Datorama 是 Angular 技術棧,Akita 最初就是為了解決Angular的狀态管理,後期開源後已經從 Angular 技術棧中剝離,對視圖層架構沒有強依賴關系。不過仍然保留了最核心的一點:基于 RxJS。在前端三大架構中,Angular 與 RxJS 的關系最緊密,Akita 最早作為 Angular 的狀态管理方案也對 RxJS 有強依賴,包括資料的封裝也是遵循 RxJS的“萬物皆流”的理念。

下圖是 Akita 的資料流:

Redux/Mobx/Akita/Vuex對比 - 選擇更适合低代碼場景的狀态管理方案

同樣是單向資料流,Akita 有以下幾個角色:

  • Store - 倉庫。Akita 中 Store 分為兩種:Basic Store 和 Entity Store。Basic Store 指的是正常的狀态資料,一般是一個純 JavaScript 對象,沒有額外附加的 API;Entity Store即實體 Store,Akita 将 Entity Store 類比為關系型資料庫的表(table),有一系列配套的 CURD API;
  • Query - 查詢。Akita 限制 Store 中的資料不能被直接讀取,必須借助一個 Query 對象做橋接(類似 Vuex的 Getter )。與 Store 一樣,Query 也分為 Basic Query 和 Entity Query,兩者的主要差別是 API 的豐富程度,Basic Query 隻有基本的條件查詢和全量查詢 API,Entity Query 搭配 Entity Store 使用,有更豐富的 API。另外,如圖中所示,Query 可以嵌套;
  • Component - 元件,即視圖層;
  • Service - 服務。Akita 中的 Service 與 Mobx 的 Action 有些類似,都是為了封裝更新 Store的邏輯,包括異步操作。
很明顯可以看出 Akita 的設計與關系型資料庫非常接近,說不定設計者是個關系型資料庫死忠粉。

Akita 與 Mobx/Flux 有一個相同的設計:沒有規範 Store 的組織模式。而且由于比較年輕,生态不繁榮,社群并沒有類似 MST 的解決方案,這造成在面對複雜資料場景下沒有既定的範式可遵循,代碼的健壯性非常依賴開發者的能力。Akita 的 Entity Store 是一個 class,可以将其他 Store 作為一個 property,以此來實作Store 的嵌套。但 JavaScript 對象之間複雜的引用關系很容易造成 memory leak,這同樣是對開發者自身能力的高要求。

Akita的優點主要有三個:

  1. 足夠簡單,核心概念比 Mobx 和 Flux 還少,對開發者來說,有足夠的定制空間。同時如上文所述,這是一把雙刃劍,對開發者的能力要求很高;
  2. 與關系型資料庫搭配順暢。Akita 的概念設計與關系型資料庫非常相似,這可能也是結合 Darorama 的業務特色,資料分析場景中的資料模型一般是一張二維表,Akita 的實體概念與 table 的搭配非常自然;
  3. 與 RxJS 無縫銜接。資料分析業務場景的事件流操作非常适合用 RxJS,Akita 底層基于 RxJS,這一點是其他競品沒有的優勢。

Akita 的缺點,如上文所述,有以下幾個:

  1. 對開發者的編碼能力要求很高;
  2. 社群不繁榮,生态不夠健全,沒有在市場中得到大範圍實踐驗證;
  3. 比較小衆,遇到問題可交流和參考的空間很小。

小結

綜合以上,各工具的基本情況如下:

是否支援劃分命名空間 是否支援時間回溯
需搭配社群解決方案
無規範無限制,開發者需自行組織代碼 插件支援

除了 Vuex 之外,其他幾個工具都沒有限制視圖層架構,隻不過 Vue + Vuex 生态比較健全,使用其他狀态管理工具的情況比較少。Redux/Mobx/Akita 目前對 React的支援都很好,要配合 Vue 架構,為了提高編碼效率和維護成本,一般需要一定的改造成本。

是否綁定視圖架構 改造成本 其他
- 不适用

由于 Vuex 不具備相容多種視圖層架構的能力,是以下文的各次元對比不再統計 Vuex。

當然理論上 Vuex 搭配 React 也不是不可能,但這種操作就太騷了,純粹為了用而用。

資料分析業務場景需要處理的資料量遠大于正常 Web 應用,不過以這種資料的量級還遠未達到需要對工具性能要求非常苛刻的程度,是以對于性能的對比僅做參考。

這裡的意思并不是說工具性能不重要,而是還沒有成為應用程式的性能瓶頸。本文調研的幾個工具都是很成熟的開源産品,已經經受了大量的業務驗證,雖然在性能上存在些許差距,但對應用性能表現的影響非常有限。

除非是涉及海量資料渲染的 web 應用,比如複雜的圖形應用(WebGL/Canvas/SVG),否則工具的性能大機率不會成為應用的性能瓶頸,尤其是比較成熟的、經過大量業務驗證的開源工具。

性能對比

以下參考自社群的兩份性能對比資料,一份是對比 Redux 和 Mobx,一份是對比 Redux 和 Akita。兩份資料都是配合 React 完成。

Redux vs Mobx

Redux/Mobx/Akita/Vuex對比 - 選擇更适合低代碼場景的狀态管理方案

這張表格來自 Mobx 作者 Michel Weststrate 的實驗資料,場景是在包含不同數量級 items 的 todolist 應用上進行增/改操作,分别統計 Redux 和 Mobx 的耗時情況。從表格裡可以看出 Mobx 有明顯的性能優勢。

這份資料僅作參考,一是因為這個實驗是2016年進行的,當時的 Redux和 Mobx 版本比較老舊。另外由于資料來自 Mobx 的作者,有些王婆賣瓜的嫌疑哈哈。不過實驗源碼是公開的,社群也比較認可。

Redux vs Akita

這份資料來自Performance Comparison of State Management Solutions in React,場景是生成一個 grid,每次生成100行,每行10列,然後随機更新1000列的資料。測試進行10次,統計總耗時(機關s)。從上圖中可以明顯看出 Akita 的耗時遠大于 Redux,更新行為的耗時對比尤其明顯。Akita 畢竟比較“年輕”,很多方面趕不上老大哥 Redux 也很正常。

綜合上面的兩份實驗資料,可以得出結論:性能方面 Mobx > Redux > Akita。

之是以上述實驗僅做參考,一方面是因為實驗的場景與真實的業務場景差距很大,現實業務中不可能隻用 Redux 或 Mobx,往往還需要配合其他解決方案,比如 redux-thunk 或 MST;另一方面是實驗本身并不絕對嚴謹,而且由于是搭配 React 進行,React 本身在不同邏輯場景下的性能表現也會直接影響實驗結果。

不過第二個實驗中涉及的一個點對本次調研工作非常有價值:狀态管理工具的批量(batch)更新能力。

批量更新

資料分析是重互動、重通信的事件密集型業務場景,很大可能在非常短的時間内發生多個事件,如果每個事件都觸發一次渲染流程(包括計算邏輯和渲染行為)的話,不僅會産生非常嚴重且無價值的性能損耗,而且如果涉及網絡請求的話還可能産生行為時序混亂進而造成結果的不正确,對業務産生無法預估的負面影響。

所謂批量更新是一個籠統的說法,在不同的工具中有不同的術語表達,不過核心目的是統一的,都是将一定時間内的 store 更新行為進行歸攏,消除中間态隻産生最終結果。這種技術手段在前端還有另外一個叫法:防抖(debounce)。

Redux 本身并不具備批量更新能力,需要搭配社群解決方案,比如 redux-batched-subscribe 和 redux-batched-actions 。

Mobx 有一個底層 API:

transaction

。這是個函數,作用是将一段時間内的所有更新行為按時序進行批量處理,所有行為處理完成之後才會通知

observer

執行回調,中間過程中不會産生任何回調。很明顯

transaction

是借鑒的資料庫中的事務概念。

Akita 與 Redux 一樣,本身同樣不具備批量更新的能力,但是由于它的底層基于 RxJS,可以使用 RxJS 的所有能力,在處理防抖場景下常用

sampleTime

debounceTime

兩個方法。

學習曲線/5分制
5 Redux本身的學習難度不高,但Redux自身無法滿足複雜需求,需要額外的社群解決方案,增加了學習成本
4 同Redux一樣,需要學習額外的社群解決方案,但成本總量比Redux低
由于Akita是基于RxJS建構,是以除了Akita本身,還需要了解RxJS的一些基本概念

風險與隐患

對于開源工具的選擇需要考慮的風險與隐患主要考慮其社群、生态以及背後團隊的響應及時性。

從這三個角度上對比,Redux 作為資曆最老的一個,各方面也是最好的,雖然目前有大量開發者對 Redux 的吐槽,但總的來說 Redux 的位置仍然很穩固,尤其是在 React社群。

Mobx 是近兩三年才逐漸占據主流,社群和生态也相對比較完善,開發團隊的響應速度也不錯。

Akita 跟前兩者比起來,最大的優勢就是開發團隊響應速度很快,目前處于上升期,開發團隊也比較活躍。但相對來說還是比較小衆,Akita 最早是面向 Angular 的,Angular 的開發者群體規模本身就比 React 和 Vue 小。 Akita 底層的 RxJS 更加小衆(雖然很好用)。目前圍繞 Akita 的複雜業務場景除了 Darorama 公司自己的業務之外,還沒有其他比較好的實踐驗證。

結論

綜合以上所有的調研次元,可以得出以下結論:

自身是否完全覆寫業務需求
是否有成熟的補足方案
支援Vue的改造成本
是否支援批量更新
學習曲線(5分制)
性能(僅參考)

綜合對比,在 Redux/Mobx/Akita 三者當中,資料分析 SDK 的狀态管理技術選型是:Mobx。

參考資料

  1. Flux架構的工作原理;
  2. 為 MobX 開啟 Time-Travelling 引擎;
  3. Build A View-Framework-Free Data Layer Based on MobX — Integration With Vue
  4. 用mobx建構大型項目的最佳實踐
  5. Becoming fully reactive: an in-depth explanation of MobX;
  6. 現代前端架構響應模型對比: Vue, Mobx, React, Redux;
  7. Mobx vs Reactive Stream Libraries;
  8. Defining data stores with Mobx;
  9. OOP and RxJS: Managing State in React with Akita;

繼續閱讀