Web 前端的状态管理(State Management)

背景

我相信很多朋友跟我一样,初次听到什么Flux, ReduxVuex状态管理的时候是一脸懵逼的。因为在外面之前前端大部分开发的时候,根本没有那么多的概念。自从 ReactJS 火爆后,什么Flux, Redux,React全家桶是一套一套接踵而来。搞的很多开发者甚是头大。所谓的 ReactJS 全家桶即ReactJS + Redux + Webpack, 当然其中的 Redux 可以用其他例如Mobx之类的替换。原本可能只是很简单的一些数据展示需求,当想用尝试使用 ReactJS 时,去 Google 搜索了一些教程,突然发现怎么用个 React 需要这么多东西。正如今年比较有名的一篇文章里面描述的那样 — ”在 2016 年学习前端是怎样一种体验”

很显然,时代在进步,技术在进步,Web 业务需求在进步,浏览器性能的大幅度提升,促使 JS 能处理越来越多的事情。为了满足越来越复杂、丰富的WebApp需求,越来越多的原本后端处理的业务逻辑开始转移到前端来处理,同时更多复杂的前端业务在浏览器上面催生,原有的很多技术体系、解决方案已经不能很好的支撑这些越来越复杂的需求了。所以当我们在面临各种业务需求的时候,必定会出现各种各样的适合不同业务需求的技术解决方案。

很多朋友刚刚上手 React 的时候,被什么 Redux, 函数式都搞的有点摸不着头脑。因为之前很多时候写前端用一个 jQuery 就足矣,当转换到 ReactJS 时,忽然多出了个 Webpack, Redux, 然而 Redux 里面又包含了什么ReducerActionState管理函数式等等概念, 搞的人的确很头大。前期较高的学习成本,造成了很多朋友就放弃了 ReactJS 的选型。而且很多开发者初期并不了解这些框架所解决的问题,缺乏足够的实践经验,造成很多人误认为这是把简单的问题越搞越复杂。可能大家回想本来很简单的问题,我用个 jQuery 就能搞定,甚至纯手撸原生 Javascript 都可以,怎么突然多出了这么多东西。例如 ReactJS 只是单纯的 View 层的解决方案,而 Redux 是一种状态管理框架,不仅支持 ReactJS,还支持Angularjs, 官方宣称的是它可以支持任务其他的视图库。正因越来越复杂的前端需求,层出不穷的前端解决方案和技术的推陈出新,造就了前端社区异常火爆的局面。而本文主要探讨前端的状态管理(State Management)

服务端渲染的 WEB 开发

服务端渲染图示

就在几年前,前端工程师的大部分工作,可能还停留在利用 CSS, HTML 切页面,然后利用 JS 做些简单的动态交互,更进一步的前端开发者可能需要懂 Java, 或者 PHP 之类的语言,因为需要将写好的页面与模板引擎完成整合。

用服务端语言(例如NodeJS, Java, Python, Ruby, PHP等等)写过 Web 的朋友应该都很清楚,以前大部分时候我们写的 Web,尤其经典的 MVC 模型。多年以前,那会还不流行前后端分离式的开发,虽然 Ajax 技术已经很流行,但是 Web 页面的功能和交互并没有那么复杂。大部分的页面点击一个连接,即请求到服务器,服务器控制路由(Router)决定响应的 View,服务器将数据库获取的数据 Model 与 HTML 模板结合,然后生成 HTML 页面响应到浏览器。那时候 Web 大部分的业务都是服务器直接处理的,很多所谓的状态管理也都是服务端直接操作操作缓存(Cache)或者数据库来完成的。所以那时候的前端并没有太多的所谓的状态需要管理,顶多大家有时候会在内存里面用一全局对象,来处理些简单的数据共享。随着 Web 前端的发展,越来越多的后端工作转移到了前端,数据的共享,同步变的异常复杂和麻烦,所以这个时候急需这种完善的状态管理解决方案的出现。

前后端分离的单页应用(SPA)

单页应用与服务器端交互图示

单页应用(Single Page Application)

利用Ajax做单页应用,经典的案例肯定就是Gmail了。早期可能大家都还用 iframe 这种古老的子页面加载方案,随着 Ajax 技术的愈发成熟和盛行,后来越来越多的 Web 应用开始利用浏览器 Hash 做路由转发,Ajax 做页面加载 的方式写无跳转状态的 Web 应用(即单页应用。后来便有了类似Backbone, Angularjs为代表的 MVVM 前端框架的诞生。

浏览器越来越快的访问性能,早就了越来越多的 PC 应用开始 WebApp 化,很多时候我们不需要安装某个应用,只需要简单的输入一个 URL 地址,便可以轻松访问我们需要的服务,相信很多朋友已经在使用Chrome上很多强大的 Web 应用了。越来越多的 Web 开始想靠近类似于 Native 应用化的体验,所以 SPA 这种类型的 Web 开发越来越受欢迎,典型的就是我们常常开发的后台管理应用了。

组件化与状态管理(Web Component And State Management)

组件直接的数据共享

Web 组件化(Component)一个是被聊透了的话题了,它的益处无需多言,更好的编码效率,更好的代码阅读性,维护性,补充 HTML5 语义化标签的不足。然而,正因为在开发越来越复杂的 SPA 时,开始将各个页面开始模块化,页面公告模块组件化,一个页面拆分成多个子组件,组件的不断复用和重新组合,之前简单的组件端到端(组件到服务器端)的数据请求变的复杂和多余,单个数据源经常在不同页面但相同组件中共享,各种路由信息(Routing)需要处理。

我们可以想象一下,当一个页面中,相同的组件获取来自同一个接口的数据,这就意味着组件共享的是相同的数据 Model。 正常逻辑下,其中一个组件如果进行了 Model 更新操作,服务器数据库的数据即相应的发生了改变,但是其他相同数据接口的组件,由于组件直接是相互隔离的,数据 Model 并不是同一个,所以组件与组件直接的数据通信便成为了一个很大的问题。当然,我们有个粗暴的解决方案,就是,在某个组件更新完数据后,我们重新reload整个页面,可这个时候整个原本想达到的 SPA 效果就没有了,体验大减,而你打开Network检测工具,你会发现整个页面发送了多个重复的接口请求,这无疑造成了很大的性能损失和资源浪费。所以才会出现 Redux,Vuex 这种专门针对状态管理的技术方案。

总结

总而言之,并不是所有的 Web 应用和使用场景都需要添加状态管理,很多时候服务端渲染任然是更好的选择,而是否需要添加状态管理框架,是用 Redux,还是 Mobx, 我们可以根据自己的业务实际情况和技术团队的偏好而添加,而有些情况下,自己创建一个全局对象可能是更适合的选择。有的人可能觉得 Redux 这种函数式编程的方式让人难以理解,那么你也可以选择 Mobx 这种面向对象编程思维的状态管理框架。如果你觉得 React 这种骑术门槛太高,适应能力差,我觉得 VueJS, Vuex 可能是更适合你的选择。

说了这么多,希望自己能解释清楚前端状态管理是怎么一回事。

原文地址http://imziv.com/blog/article/read.htm?id=80

最后修改于 2017-01-08