hello~亲爱的看官老爷们你们好~有一段时间没写文章了,最近忙于为一个对内的数据可视化平台进行彻底的先后端分离。原来的项目是一个基于 Vue
的单页应用,重构后接入 Node
做为中间层,达到彻底的先后端分离。前端
因为项目相对简单,成本并非过高。下文将简单介绍一下使用的技术栈与分离后的收益,重点是对基于 Node
作先后端分离的一点思考。数据库
大约是去年11月底入职新东家,接手一个仅 对内 的数据分析系统。新入职固然是但愿作出点成绩,在更改部分 UI 与优化部分功能以后,发现页面性能仍是比较低。排查后发现获取数据的接口没有缓存,也不是基于 RESTful
的,浏览器缓存彻底不起做用。期间也经历了后端修改接口,前端代码大面积修改的状况。json
基于后端同窗不熟悉前端机制,我也抱着方便往后搞事情的心态,在屡次滚地板以后,部门 Leader 赞成接入 Node
做为中间层。后端
在肯定接入 Node
后,首先要作的就是技术选型。Node
通常就是在 Express
、Koa
与 Egg
中选。在中间件的使用上,我的偏好 Koa
,于是只好和 Express
说再见了 。Egg
是在 Koa
上做了强约束,规定代码编写、目录结构等。浏览器
选型时我与前端 Leader 讨论了无数次,他认为 Egg
约束太多,扩展性较差,如若出现框架底层的 Bug 则难于处理,于是偏向于使用 Koa
。这样的顾虑十分合理,然而对于如今的项目而言,不太可能有功能会超出 Egg
所提供的,反而 Egg
所提供的功能能为项目搭建与维护减小很多的成本。至于约束,我的认为这反而是一件好事,必定程度上解决了多人开发时代码的组织问题。缓存
考虑再三后,决定使用 Egg
做为 Node
的框架。安全
因为项目不算十分复杂,接入的过程算是波澜不惊。惟一的麻烦是工期比较紧,于是分两步走:一期先接入 Node
,全部页端请求原样转发 Java
,返回的结果原样转发页端。二期对数据获取的接口进行整合与优化以提高性能。完成后收益仍是客观的,贴两张图展现下成果。数据结构
原来某页面的性能(全部请求都是 Post 的):架构
接入 Node
相同页面的性能(转为方法为 Get):框架
能够看到,不管是数据下载量仍是响应时间等指标,耗时均有下降。固然,这是创建在接入 Node
后我对接口进行了整合与缓存优化等措施后的对比。若是都是首次访问,公司内网 WiFi 环境下与原来的性能会有稍差一点,总体加载时间略高于 Java
直出50ms不到。也用过 Chrome 模拟弱网环境,耗时与 Java
直出基本一致。
并且开发体验上也比以前舒服得多,算是达到了接入 Node
前定下的目标:接入后在支持相同功能的状况下性能提升30%;在相同的开发时间内,完成相同的需求,但有更好的开发体验及更好的页端性能。
小结一下,前端的一切优化都是在模板与获取模板所需数据上进行优化,使用 Angular
、React
与 Vue
等框架构筑的单页应用,解决了模板的问题,能够再也不让后端去动咱们的模板。可是获取所需数据仍依赖于后端,很多单页应用交互上已经足够复杂,若是还需维护一套复杂的获取与整合数据的逻辑,仍是十分头疼的。于是多接入一层 Node
处理数据的获取与整合,尽最大努力去优化页端的请求接口,让页端专一于交互,在条件成熟的状况下,是十分值得的。
如若就为了推广 Node
,本文应该是把上面的步骤写详细,小结完就该结束了,这和不少大佬的实践文章一致(固然我写得不够好~)。然而和两位 Leader 的讨论过程当中,感谢他们对 Node
技术抱有怀疑,提出了很多有意思的问题,结合我本身的思考,整理成提问形式呈现给你们。
为什么接入
Node
做为中间层,和公司现行的PHP
有何区别?
没有区别!事实说,Node
能作的 PHP
同样能作。那么问题就转换为 Node
的意义是什么,为什么摈弃公司相对成熟的 PHP
方案而转向 Node
?
我认为后端服务主要是稳定为主,业务调整不会特别频繁。而对于前端而言,业务频繁调整简直司空见惯,若是先后端耦合在一块儿,频繁让后端发版不是可取之策。同时,先后端对数据结构的要求及对其控制的粒度也大不相同。写得好 PHP
的同窗不必定写得好前端,写得好前端的同窗不必定写得好 PHP
。对于专业的领域,仍是应该由专业的人去作,让前端控制整个模板及模板依赖的数据,对提升项目质量有很大的帮助。说句玩笑话,后端就搞搞数据库,吐吐 json
就好,前端就拿一下数据,切切页面就好。
进一步而言,前端若要接入 SSR
之类的功能,Node
还真比 PHP
有优点得多,也算是为往后搞事情作铺垫吧。
接入
Node
后性能会有多大提升?
不必定有提升,甚至有降低。此问题是我一期完成以后,测试页端性能时发现的。测试时,Node
除了将全部的需求原样转发外,还加了协商缓存,然而响应时间却更慢了。
接入前(为 Post 请求):
接入后(为 Get 请求):
正常来讲,获取 10k 左右的数据时,协商缓存如若命中即返回 304,省略了下载的过程,理应更快的。经过打点,发现 Node
转发请求耗时额外增长 10ms 左右,然而在全公司内网 WiFi 环境下,总体下载时间不到 160ms。
于是引入 Node
不必定会有性能的提升,反而会由于多引入一层,而致使性能耗损。在对内的项目中或性能尚可的项目中,提升性能不足以成为接入 Node
的关键理由。换句话说,接入 Node
以后,在优化页端请求以前,并不可能为应用性能带来飞跃。
这个问题也算是我对 Node
态度转变的起点,开始从无脑支持接入 Node
到辩证地推敲,也引出以后的的问题。
接入
Node
有什么弊端?
前端的能力越强,意味着责任越多。例如以前多是 Java
作的安全防御,可能就会下沉到 Node
端,这对大多数前端同窗而已都是比较陌生的领域。
投入的成本与产出也是值得商榷的事情,毕竟 Node
再贴近前端,也始终是属于后端的领域。先后端思想不太同样,用前端的思惟写后端,极可能写出十分糟糕的代码,轻则影响性能,重则内存泄漏。接入 Node
层后它反而成为拖累,相信你们也不肯看见。
毕竟 Node
对于很多公司而言是比较新的领域。尽管可能知道接入 Node
好处很多,但如何接入,接入后它能作什么,你们可能比较模糊。如何花最少的代价,平滑地接入 Node
的同时,最大限度的复用现有架构,也是个很多的挑战。
既然如此,没有
Node
适用的场景吗?
有。正如前文所说,Node
的意义是在于让前端掌握模板与模板所依赖数据,不妨从这两方面去进行考虑。如若重 SEO 的同时,页面交互相对复杂,这时候接入 Node
做为中间层,我认为就是最佳实践。
其次是后端架构不断演变,开始转向微服务化以后,前端感到接口碎片化开始带来很多麻烦后,就应该考虑接入 Node
整合接口了。
总的来讲,何时接入 Node
, 有点像何时引入 Redux
或 Vuex
。当你感受到麻烦后,只要你知道还有这个选项,天然而言地就会想到用它。
综上所述,在如下场景中,我认为接入 Node
是最佳实践:
SSR
、PWA
等。如若只是性能问题,引入 Node
不必定会有改善,须要根据实际状况进行分析。至于后端的接口设计太丑陋、返回的数据结构不符合前端使用等问题,在应用规模不大的状况下,其实都是能够和后端同窗进行沟通的,以此接入 Node
不必定是最佳的实践,须要好好思量。
可是,坚定反对只是由于现有架构比较熟悉而不肯改变,始终抱着错误的方案不去解决的作法,这绝对是舍本逐末。我始终认为,只要是对的事情,尽管过程再艰难,亦应该朝着对的方向前进。
以上是我的的一点浅见,感谢各位看官大人看到这里。知易行难,但愿本文对你有所帮助~谢谢!