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

cskr1636 7年前
   <h3>背景</h3>    <p>我相信很多朋友跟我一样,初次听到什么 Flux ,  Redux ,  Vuex , 状态管理 的时候是一脸懵逼的。因为在外面之前前端大部分开发的时候,根本没有那么多的概念。自从ReactJS火爆后,什么 Flux, Redux,React全家桶 是一套一套接踵而来。搞的很多开发者甚是头大。所谓的ReactJS全家桶即 ReactJS + Redux + Webpack , 当然其中的Redux可以用其他例如 Mobx 之类的替换。原本可能只是很简单的一些数据展示需求,当想用尝试使用ReactJS时,去Google搜索了一些教程,突然发现怎么用个React需要这么多东西。</p>    <p>很显然,时代在进步,技术在进步,Web业务需求在进步,浏览器性能的大幅度提升,促使JS能处理越来越多的事情。为了满足越来越复杂、丰富的 WebApp 需求,越来越多的原本后端处理的业务逻辑开始转移到前端来处理,同时更多复杂的前端业务在浏览器上面催生,原有的很多技术体系、解决方案已经不能很好的支撑这些越来越复杂的需求了。所以当我们在面临各种业务需求的时候,必定会出现各种各样的适合不同业务需求的技术解决方案。</p>    <p>很多朋友刚刚上手React的时候,被什么Redux, 函数式都搞的有点摸不着头脑。因为之前很多时候写前端用一个jQuery就足矣,当转换到ReactJS时,忽然多出了个Webpack, Redux, 然而Redux里面又包含了什么 Reducer 、 Action 、 State管理 、 函数式 等等概念, 搞的人的确很头大。前期较高的学习成本,造成了很多朋友就放弃了ReactJS的选型。而且很多开发者初期并不了解这些框架所解决的问题,缺乏足够的实践经验,造成很多人误认为这是把简单的问题越搞越复杂。可能大家回想本来很简单的问题,我用个jQuery就能搞定,甚至纯手撸原生Javascript都可以,怎么突然多出了这么多东西。例如ReactJS只是单纯的View层的解决方案,而Redux是一种状态管理框架,不仅支持ReactJS,还支持 Angularjs , 官方宣称的是 它可以支持任务其他的视图库 。正因越来越复杂的前端需求,层出不穷的前端解决方案和技术的推陈出新,造就了前端社区异常火爆的局面。而本文主要探讨前端的状态管理(State Management)</p>    <h3>服务端渲染的WEB开发</h3>    <p style="text-align: center;"><img src="https://simg.open-open.com/show/1716bad0ecab652b17b73f181c77d2c3.jpg"></p>    <p>服务端渲染图示</p>    <p>就在几年前,前端工程师的大部分工作,可能还停留在利用CSS, HTML切页面,然后利用JS做些简单的动态交互,更进一步的前端开发者可能需要懂Java, 或者PHP之类的语言,因为需要将写好的页面与模板引擎完成整合。</p>    <p>用服务端语言(例如 NodeJS, Java, Python, Ruby, PHP 等等)写过Web的朋友应该都很清楚,以前大部分时候我们写的Web,尤其经典的MVC模型。多年以前,那会还不流行前后端分离式的开发,虽然Ajax技术已经很流行,但是Web页面的功能和交互并没有那么复杂。大部分的页面点击一个连接,即请求到服务器,服务器控制路由(Router)决定响应的View,服务器将数据库获取的数据Model与HTML模板结合,然后生成HTML页面响应到浏览器。那时候Web大部分的业务都是服务器直接处理的,很多所谓的状态管理也都是服务端直接操作操作缓存(Cache)或者数据库来完成的。所以那时候的前端并没有太多的所谓的状态需要管理,顶多大家有时候会在内存里面用一全局对象,来处理些简单的数据共享。随着Web前端的发展,越来越多的后端工作转移到了前端,数据的共享,同步变的异常复杂和麻烦,所以这个时候急需这种完善的状态管理解决方案的出现。</p>    <h3>前后端分离的单页应用(SPA)</h3>    <p style="text-align: center;"><img src="https://simg.open-open.com/show/1e97c8871b89fe23d0f026365914cf5e.jpg"></p>    <p>单页应用与服务器端交互图示</p>    <p>单页应用(Single Page Application)</p>    <p>利用 Ajax 做单页应用,经典的案例肯定就是 Gmail了 。早期可能大家都还用iframe这种古老的子页面加载方案,随着Ajax技术的愈发成熟和盛行,后来越来越多的Web应用开始利用浏览器Hash做路由转发,Ajax做页面加载 的方式写无跳转状态的Web应用(即单页应用。后来便有了类似 Backbone ,  Angularjs 为代表的MVVM前端框架的诞生。</p>    <p>浏览器越来越快的访问性能,早就了越来越多的PC应用开始WebApp化,很多时候我们不需要安装某个应用,只需要简单的输入一个URL地址,便可以轻松访问我们需要的服务,相信很多朋友已经在使用 Chrome 上很多强大的Web应用了。越来越多的Web开始想靠近类似于Native应用化的体验,所以SPA这种类型的Web开发越来越受欢迎,典型的就是我们常常开发的后台管理应用了。</p>    <p>组件化与状态管理(Web Component And State Management)</p>    <p style="text-align: center;"><img src="https://simg.open-open.com/show/19f815327fe54549338e01ae077f8736.jpg"></p>    <p>组件直接的数据共享</p>    <p>Web组件化(Component)一个是被聊透了的话题了,它的益处无需多言,更好的编码效率,更好的代码阅读性,维护性,补充HTML5语义化标签的不足。然而,正因为在开发越来越复杂的SPA时,开始将各个页面开始模块化,页面公告模块组件化,一个页面拆分成多个子组件,组件的不断复用和重新组合,之前简单的组件端到端(组件到服务器端)的数据请求变的复杂和多余,单个数据源经常在不同页面但相同组件中共享,各种路由信息(Routing)需要处理。</p>    <p>我们可以想象一下,当一个页面中,相同的组件获取来自同一个接口的数据,这就意味着组件共享的是相同的数据Model。 正常逻辑下,其中一个组件如果进行了Model更新操作,服务器数据库的数据即相应的发生了改变,但是其他相同数据接口的组件,由于组件直接是相互隔离的,数据Model并不是同一个,所以组件与组件直接的数据通信便成为了一个很大的问题。当然,我们有个粗暴的解决方案,就是,在某个组件更新完数据后,我们重新 reload 整个页面,可这个时候整个原本想达到的SPA效果就没有了,体验大减,而你打开 Network 检测工具,你会发现整个页面发送了多个重复的接口请求,这无疑造成了很大的性能损失和资源浪费。所以才会出现Redux,Vuex这种专门针对状态管理的技术方案。</p>    <h3>总结</h3>    <p>总而言之,并不是所有的Web应用和使用场景都需要添加状态管理,很多时候服务端渲染任然是更好的选择,而是否需要添加状态管理框架,是用Redux,还是Mobx, 我们可以根据自己的业务实际情况和技术团队的偏好而添加,而有些情况下,自己创建一个全局对象可能是更适合的选择。有的人可能觉得Redux这种函数式编程的方式让人难以理解,那么你也可以选择Mobx这种面向对象编程思维的状态管理框架。如果你觉得React这种骑术门槛太高,适应能力差,我觉得VueJS, Vuex可能是更适合你的选择。</p>    <p>说了这么多,希望自己能解释清楚前端状态管理是怎么一回事。</p>    <p> </p>    <p>来自:http://imziv.com/blog/article/read.htm?id=80</p>    <p> </p>