近期准备开发一个数据分析 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 集成进来,以可视化的形式提供分析相关的功能。下图展示的是网易有数报告定制的页面:
数据分析是一种类似的低代码的业务场景,从技术角度上有以下特征:
- 数据量大且结构复杂;
- 事件流复杂、高频且时序敏感;
- 组件结构复杂且互相之间存在大量的数据共享。
除此之外,之所以要做一个分析 SDK而不是分析平台,是因为中台的服务产出需要支持前台业务的接入,分析 SDK 的目标用户是前台业务部门的各个分析平台。在这个前提下,分析 SDK 对技术有另外一个额外要求:
- 支持前台分析平台的技术栈。
而前台不止一个,不同业务线的技术栈也不统一,前端技术栈的契合度主要是组件要支持多种视图层框架,比如React、Vue2、Vue3甚至Angular,所以分析 SDK的技术架构应当尽量减轻对视图层框架的依赖程度,将核心业务逻辑从视图层抽离出来。这样的好处能够降低支持不同视图层框架时所投入的人力成本、时间成本和维护成本。这就是本文开头所说的为什么要构建与视图框架无关的数据/状态管理层的原因。「Smart Modeling,Dumb View」,即逻辑集中在数据层,视图层尽量只做展示(类似 React 的 Pure Component)。
结合分析 SDK的定位和业务场景,可以提炼出对状态管理工具的几点具体需求:
- 支持 state 按子模块划分命名空间,以便支持复杂数据模型;
- 与视图层框架没有强绑定关系,以便支持多种视图层框架;
- 支持时间回溯,比如undo/redo,这是编辑器的基本操作。
数据流
目前绝大多数状态管理工具都遵循单向数据流原则,这项原则最早是由 Flux 带入到前端领域,所以在了解各个状态管理工具的数据流之前,有必要先搞清楚 Flux 架构。
这部分只考虑正常交互场景下的数据流向,也就是只考虑由view层触发数据变动的情况,不考虑单元测试等非常规交互场景。
Flux
- 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 数据流如下:
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
Redux 遵循 Flux 的单向数据流思想,与 Flux 不同的是,Redux 没有 Dispatcher 的概念,而是将本属于 Dispatcher 的 dispatch
方法内聚到了 Store 对象上。
- 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
Vuex 是针对 Vue 的一种特异化的 Flux,保留了单向数据流的核心概念,同时吸取了部分 Redux 的理念。跟 Flux/Redux相比,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
Mobx 是一个基于函数式响应式编程(Functional Reactive Programming,简称 FRP)的状态管理解决方案,同样遵循单向数据流原则。
理解 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 的定义如下:
有些不好理解,其实可以简单粗暴的把 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
Akita是来自 Datorama 公司研发团队的前端状态管理方案,跟其他几个竞品相比,Akita 的资历是最浅的。不过 Akita有一个优势:与 Mobx一样,Akita 经过了与数据分析类似业务场景的实践验证。Datorama 是一家提供数据解决方案的公司,它的业务场景与数据分析有很大的重合度,Akita 已经在 Datorama 的一些产品中得到了实践和验证。
Datorama 是 Angular 技术栈,Akita 最初就是为了解决Angular的状态管理,后期开源后已经从 Angular 技术栈中剥离,对视图层框架没有强依赖关系。不过仍然保留了最核心的一点:基于 RxJS。在前端三大框架中,Angular 与 RxJS 的关系最紧密,Akita 最早作为 Angular 的状态管理方案也对 RxJS 有强依赖,包括数据的封装也是遵循 RxJS的“万物皆流”的理念。
下图是 Akita 的数据流:
同样是单向数据流,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的优点主要有三个:
- 足够简单,核心概念比 Mobx 和 Flux 还少,对开发者来说,有足够的定制空间。同时如上文所述,这是一把双刃剑,对开发者的能力要求很高;
- 与关系型数据库搭配顺畅。Akita 的概念设计与关系型数据库非常相似,这可能也是结合 Darorama 的业务特色,数据分析场景中的数据模型一般是一张二维表,Akita 的实体概念与 table 的搭配非常自然;
- 与 RxJS 无缝衔接。数据分析业务场景的事件流操作非常适合用 RxJS,Akita 底层基于 RxJS,这一点是其他竞品没有的优势。
Akita 的缺点,如上文所述,有以下几个:
- 对开发者的编码能力要求很高;
- 社区不繁荣,生态不够健全,没有在市场中得到大范围实践验证;
- 比较小众,遇到问题可交流和参考的空间很小。
小结
综合以上,各工具的基本情况如下:
是否支持划分命名空间 | 是否支持时间回溯 | |
---|---|---|
Redux | 是 | 是 |
Vuex | 是 | 是 |
Mobx | 需搭配社区解决方案 | 需搭配社区解决方案 |
Akita | 无规范无限制,开发者需自行组织代码 | 插件支持 |
与视图框架的绑定程度和改造成本
除了 Vuex 之外,其他几个工具都没有限制视图层框架,只不过 Vue + Vuex 生态比较健全,使用其他状态管理工具的情况比较少。Redux/Mobx/Akita 目前对 React的支持都很好,要配合 Vue 框架,为了提高编码效率和维护成本,一般需要一定的改造成本。
是否绑定视图框架 | 改造成本 | 其他 | |
---|---|---|---|
Redux | 否 | 高 | |
Vuex | 是 | - | 不适用 |
Mobx | 否 | 低 | 需搭配社区解决方案 |
Akita | 否 | 中 |
由于 Vuex 不具备兼容多种视图层框架的能力,所以下文的各维度对比不再统计 Vuex。
当然理论上 Vuex 搭配 React 也不是不可能,但这种操作就太骚了,纯粹为了用而用。
性能
数据分析业务场景需要处理的数据量远大于常规 Web 应用,不过以这种数据的量级还远未达到需要对工具性能要求非常苛刻的程度,所以对于性能的对比仅做参考。
这里的意思并不是说工具性能不重要,而是还没有成为应用程序的性能瓶颈。本文调研的几个工具都是很成熟的开源产品,已经经受了大量的业务验证,虽然在性能上存在些许差距,但对应用性能表现的影响非常有限。
除非是涉及海量数据渲染的 web 应用,比如复杂的图形应用(WebGL/Canvas/SVG),否则工具的性能大概率不会成为应用的性能瓶颈,尤其是比较成熟的、经过大量业务验证的开源工具。
性能对比
以下参考自社区的两份性能对比数据,一份是对比 Redux 和 Mobx,一份是对比 Redux 和 Akita。两份数据都是配合 React 完成。
Redux vs Mobx
这张表格来自 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分制 | 说明 | |
---|---|---|
Redux | 5 | Redux本身的学习难度不高,但Redux自身无法满足复杂需求,需要额外的社区解决方案,增加了学习成本 |
Mobx | 4 | 同Redux一样,需要学习额外的社区解决方案,但成本总量比Redux低 |
Akita | 4 | 由于Akita是基于RxJS构建,所以除了Akita本身,还需要理解RxJS的一些基本概念 |
风险与隐患
对于开源工具的选择需要考虑的风险与隐患主要考虑其社区、生态以及背后团队的响应及时性。
从这三个角度上对比,Redux 作为资历最老的一个,各方面也是最好的,虽然目前有大量开发者对 Redux 的吐槽,但总的来说 Redux 的位置仍然很稳固,尤其是在 React社区。
Mobx 是近两三年才逐渐占据主流,社区和生态也相对比较完善,开发团队的响应速度也不错。
Akita 跟前两者比起来,最大的优势就是开发团队响应速度很快,目前处于上升期,开发团队也比较活跃。但相对来说还是比较小众,Akita 最早是面向 Angular 的,Angular 的开发者群体规模本身就比 React 和 Vue 小。 Akita 底层的 RxJS 更加小众(虽然很好用)。目前围绕 Akita 的复杂业务场景除了 Darorama 公司自己的业务之外,还没有其他比较好的实践验证。
结论
综合以上所有的调研维度,可以得出以下结论:
Redux | Mobx | Akita | |
---|---|---|---|
自身是否完全覆盖业务需求 | 否 | 否 | 否 |
是否有成熟的补足方案 | 是 | 是 | 是 |
支持Vue的改造成本 | 高 | 中 | 中 |
是否支持批量更新 | 是 | 是 | 是 |
学习曲线(5分制) | 5 | 4 | 4 |
风险与隐患 | 低 | 低 | 中 |
性能(仅参考) | 中 | 高 | 低 |
综合对比,在 Redux/Mobx/Akita 三者当中,数据分析 SDK 的状态管理技术选型是:Mobx。
参考资料
- Flux架构的工作原理;
- 为 MobX 开启 Time-Travelling 引擎;
- Build A View-Framework-Free Data Layer Based on MobX — Integration With Vue
- 用mobx构建大型项目的最佳实践
- Becoming fully reactive: an in-depth explanation of MobX;
- 现代前端框架响应模型对比: Vue, Mobx, React, Redux;
- Mobx vs Reactive Stream Libraries;
- Defining data stores with Mobx;
- OOP and RxJS: Managing State in React with Akita;