「前端数据流」发展简史
数据流的定义
数据流在前端应用中天然存在,无论是使用热门UI框架/库,还是原生html + js,都不可避免地需要维护数据集合以及数据在应用中的流动。
在聊数据流之前,我们先来尝试给它下一个定义。
数据
数据可以视作状态的集合
。
现今的前端开发基本都可以纳入到MVW(Model-View-Whatever)
模式,热门的前端框架/库,如react、vue、angular、svelte、solid等,都是在帮开发者接管Model和View之间的转化与互动,只是形式(MVVM、MVC、MVP等)和实现(运行时/virtual dom,模板,静态编译等)不同。
但对开发者来说,页面开发大都是数据驱动,数据即页面,开发大多数时候是在维护状态和页面的映射关系
。
MVVM:
流
先来看一下维基百科里对数学中流的定义:
一个流用数学方式形式化了“取决于时间的变化”的一般想法。更形式地说,流是单参数群在一个集合上的群作用
这段话虽然看不懂,但可以我们提取几个关键词:时间的变化
,集合
,作用
。
数据流
据此,姑且对数据流下一个自认为的定义(不一定对):
随时间连续变化、可响应作用的状态集合
。
数据流的历史
进入主题,我们以前端发展史为线索,来聊一聊数据流管理方案的演变。
一、上古时期
这个时期的是静态页面
向动态生成技术
的过渡。
- 1993年,HTML1.0版本发布,最早的HTML页面是完全静态的,预先编写好了存放在Web服务器上,浏览器请求某个URL时服务器直接返回对应的页面。此时数据即是HTML上的代码块。
- 随着网页用户量的增多,动态生成HTML的需求变大,最早的做法是服务器接到请求后,通过C、C++等编程语言,动态拼接HTML字符串输出给浏览器,这类技术被统称为
CGI
(Common Gateway Interface)。
- 后来人们发现,拼接HTML字符串的时候,大部分HTML结构和页面生成逻辑是不变的,变化的只有不同用户对应的不同数据,于是又出现了生成动态HTML的新方式:
ASP、JSP和PHP
。此时已经开始体现数据即页面
的思想。例如在ASP中,在页面模板里用<%=var%>
标记变量,再结合循环、条件判断等生成页面,比拼接字符串优雅简洁得多。
二、原始时期 - 事件驱动
- 1995年JavaScript被设计出来,1997年Javascript 1.0版本(ES1)正式发布,但早期JS只是被用来做简单的交互和操作DOM节点。
- 2005年,跨时代的AJAX出现,促进了前后端分离和SPA的流行,同时搭配JQuery等工具,前端开始接管应用的数据管理。但由于这时前端开发还涉及大量DOM操作,设计模式更多的是停留在
命令式、事件驱动
阶段。
三、发展时期 - 数据驱动
这一时期,数据驱动视图
成为前端页面的主流实现思想。订阅/发布
、响应式/依赖收集
、可变与不可变
、集中式与渐进式
的概念纷纷被应用于前端数据管理方案,也因此出现了各种实践和尝试,并逐渐形成了目前主流的三大流派(这个后面再总结)。
先来看这一时期的重要事件节点:
-
2009~2010年,Backbone和Angular1.0等初代前端框架兴起,在前端引入
MV*
(MVC、MVP、MVVM)架构,将数据(Model)和视图(View)分离,开始启发各种对数据与视图关系的思考。 -
2012年RxJS发布,它是微软
ReactiveX编程
理念的JavaScript版本,核心概念是观察者模式
、迭代器模式
和函数式编程
。RxJS也是响应式、流式
这一流派的代表。 -
2013年React发布,意义也是里程碑式的:
- React对
UI=render(data)
哲学、即函数式组件的极致追求,以及创新的虚拟DOM
,让开发者可以把目光从DOM操作转移到数据和逻辑,极大推动了数据驱动视图
思想的发展。 - React的组件通讯模式,以及结合Redux的实践,使
单向数据流
成为主流(Vue1.0版本和早期的Angular都还是双向数据流,后期也改成了单向) - React将
不可变数据(Immutable)
带入了人们的视野,immutable.js(与react同为facebook的产物)和immer的流行react都功不可没。
- React对
-
2015年Redux发布,它基于
flux
,结合单向数据流、immutable
的思想,提出了一种集中式
的状态管理方案,以解决组件间通信和共享状态的问题。
- 2014~2015年,Vue和Vuex相继发布,它们的数据流模式参考了Flux/Redux,也一样是集中式管理,不同的是Vuex采用了
依赖收集、响应式和可变数据(mutable)
,相比Redux的广播式推送,拥有理论上性能更好的精准定向更新能力。
-
2016年,Mobx发布,它的思想和Vue/Vuex很像,同样是基于
mutable + proxy
,不同的是,它在实现上抽象了应用程序的State(状态)
、Actions(动作)
、Derivations(派生)
的概念,是一个UI无关的状态管理库,可以结合中间件集成到react等UI库中(想详细了解可看我的另一篇文章)。 -
2020年前后,主流UI框架/库的
渐进式/分布式
状态管理方案开始流行:Recoil、Pinia等。前面说过,Redux和Vuex都是集中式的,这和如今的前端原子化、组件化、静态化
思潮似乎是相悖的。于是Facebook推出了React的状态管理方案Recoil,而Vue团队也推荐将Pinia作为Vuex的替换方案。 -
此外,近几年也出现了如hox、zustand、jotai等优秀的状态管理实践,各花入各眼。
三大流派
到这里可以总结一下如今前端状态管理的三大流派了:
-
函数式,不可变数据
:这其中集中式的代表是Redux,渐进式有recoil等。 -
响应式,依赖追踪,可变数据
:集中式:Vuex;渐进式:Mobx,Pinia等。 -
响应式,流式
:RxJS。
总结
整体而言,前端数据管理的大趋势是从事件驱动
变为数据驱动
,无论心智模型是Model-View-Whatever,这都是几乎无争议的。
实现方式上,大致也离不开函数式/不可变数据
和响应式/可变数据
两大类。
同时近年受组件化、原子化的影响,集中式
的数据管理有过渡到渐进式
的趋势,这也使对数据的静态分析、异步加载、代码切割(code splitting)
等优化成为可能,就跟一般的组件一样。
内容就到这里了,如有错误还请指正。这是我数据流相关的第三篇文章,也给另外两篇打个广告:
下一篇会详细探讨各主流数据流方案的特点,做一个横向对比(如果还有的话)。
转载自:https://juejin.cn/post/7216147029230321701