前后端分离,目前对于一个前端开发者来说,或者将其放在软件开发领域的历史背景下,都是再平常不过的一件事情了。17 年时进行了一个前后端彻底分离方案的实践,每次想起来这个方案时,总觉得它不够完美。现在将其写下来和大家交流,期望可以促进方案的后续完善。
自从接触前端开发,一共接触到了三种前端项目发布的方式:
刚加入丁香园前端团队时,前后端分离的 SPA 项目的实现方式是:前端和服务端项目是两个代码仓库,HTML 模板由服务端语言(JSP/PHP)输出,HTML 引用的前端资源是通过前端资源发布系统发布到 cdn 上。涉及到 cdn,就会面临 cdn 缓存的问题。解决 cdn 缓存问题的方案是传统的时间戳机制。具体操作流程是服务端提供一个更新时间戳的接口,当前端每次发布新版本后,去调用更新时间戳的接口。
基于时间戳机制的前端项目发布流程大致为:
看上去这个流程很简单高效,对不对?让我们来根据实际情况来细化一下这个流程:
流程细化之后,我们可以把流程分为5步,平均算下来每次前端同学进行一次项目发布,大概需要3分钟。在等待发布系统构建资源的时候,前端同学可以并行的去做一些放松的事情,比如:去餐吧喝杯咖啡,上个厕所,随手修个 bug。放松之后,更新一下时间戳,新版本发布便大功告成。接下来便可以进入愉悦的新需求开发之旅了,一切都显得如此惬意。
去年的我,也是这样认为的。因为当时在负责的新版调查问卷(SPA)和 Insight(可以看做 n 个 SPA)等项目,大概平均每天发布一次,所以用来发布的时间成本还是能接受的。
16年年底时,加入了大众医学部,开始和伙伴们一起负责来问丁香医生等项目。项目依旧是前后端分离的 SPA,构建好的前端资源依旧是发布到 cdn,解决 cdn 缓存问题同样采用的是时间戳机制。一切都是熟悉的配方,熟悉的味道。当参与了一段时间的需求迭代后,我发现事情似乎没有想象的那么简单。
让我有这种感受的原因,主要有两点:
此时细化的一次发布流程变为:
一次前端发布的时间,平均在7分钟左右。在实际工作中,需要在测试环境、(预发环境)、生产环境进行发布。从团队的角度来看,管理后台等项目也在采用这种发布方式。毛估一下,每周团队在项目发布上就需要花费 2 ~ 3 个小时((7min * 2 * 2 * 5)/ 60)。
此外,这种前后端分离的方式还有以下几个问题:
为了解决上述问题,我设计了一个的方案:
方案说明:
方案确定后,在团队小伙伴的配合下,该方案在一个流量较小的项目上线了。
上述方案存在一个问题的:在原有的技术体系中,引入了 Node.js。本质上是在稳定的技术体系下,增加了技术复杂度。因此,在不增加技术复杂度的前提下,需要开始探索新的解决方案。在后端同学的配合下,新方案相比于引入 Node.js 方案改动如下:
方案上线后,前端项目的发布流程变为:
前端项目发布这件事,终于变成了点击一下发布按钮,整件事情就做好了。整个发布流程耗时变为不到一分钟。此外,当前端需要改变 HTML 模板时,也不再需要将文件发给后端同学,苦苦等待后端项目的发版。
该方案上线后,组内同学在周报中提及到的使用新方案后的感受为:
为了方便前端同学获取同步模板的进展,在发布系统中增加了同步过程的提醒:
上述方案相比于 JSP/PHP 提供 HTML 模板存在一个问题,就是在前端在构建 HTML 时,(暂时)不能将应用初始化的数据放入 HTML 中。解决方案是服务端提供一个接口,在应用启动时去调用该接口获取初始化数据。
对于前端加载优化,整体上思路上是需要减少网络请求的,而此方案却在增加网络请求,这意味着页面加载时间会变长。但是综合利弊之后,还是决定采用这个方案。
最终方案上线后,其实心中已经做好了页面平均加载时间会变长的心理准备,但是有些意外的是,几天后去 mta 看数据发现全国范围内平均响应时间缩短了 0.2s 左右。为什么不升反降,目前我还不能得出一个准确的答案。猜测的一个原因是: hash 值的方案避免了用户进行不必要的资源更新。
上述方案虽然做到了前端项目的一键发布,但是还不够称作为一个完善的解决方案。因为该方案只是解决了 SPA 类型项目的发布问题,对于之前“套模板”重 SEO 的项目而言,并不是很适用。(提到 2018 年的技术浪潮下,如何开发一个重 SEO 的网站这个话题,又可以写一篇文章了,其中的心路历程还是蛮坎坷的)
言归正传,在前端资源发布系统层面,该方案可以考虑去增加文件历史和发布回滚功能,以备不时只需。
这个方案是和业务线的服务端同学配合实现的,从公司层面来看,可以考虑的点是是否可以将这个方案做成一个通用的服务。
在和团队的交流时,相学长提出可以将 HTML 引用的资源抽象成 JSON Tree 进行存储。之前看过一些类似的解决方案,不过目前自己还是更倾向于分开的“更彻底”,这样可以让服务端同学更安心的提供接口。
由于水平有限,欢迎大家对此方案提出建议。非常期待。
本文作者:丁香园前端工程师 @志遥