一次前端解构的尝试

前端开发由于单页应用的兴起,前端是越来越工程化,代码量越来越大。不可避免的需要将工程解构,然后分派给各个团队单独开发。

我们希望能类似后端微服务的效果,独立开发,独立部署,而对用户而言是无感知的。

First Split

于是我们基于页面按照团队拆分,将不同的业务页面按业务分成不同的业务线,然后独立开发,独立部署。本质上不同团队已经在开发不同网站了,不过通过一层代理层将各个站点连接起来,让终端用户认为他们仍在使用同一种应用。

独立开发部署架构图.png

此拆分可以将业务部分拆分较细粒度,允许团队独立开发,最后仅仅需要测试人员根据业务要求验证各个业务集成时候是否符合需求即可。

对于大部分开发场景而言,此方案就足够了。不过既然不同团队开发的站点其实是同一个应用,页面上可能有很多共同元素(比如常见的DashBoard应用常常有用户Profile元素,以及切换业务用的Menu)。业务切换回导致页面的Reload,共有元素必定会导致浏览器重新执行,而且除此之外,单页应用框架现在都比较重,首屏加载中框架的启动会占据大部分时间,从而每次业务切换Reload总会导致一部分JS引擎执行时间花费在这些公共部分的重新渲染上,造成用户体验上感觉加载性能慢。

公共部分示意图.jpg

Next Split

虽然上诉方案带来了非常大的开发便利性,但是导致了的用户体验的下降。

我们希望能保持上诉方案中,既能保持各个团队独立开发,独立部署的好处,又能不牺牲页面切换中,由单页应用拆分后带来的应用框架重复价值的性能损失。

所以我们在前诉方案的基础上尝试了我们称为Dynamic Route Loading的方案尝试,确实提升了用户体验的上升,但也带来了很大的缺陷,可供大家作为思路参考。

本思路的核心为:当前的单页应用均具有路由功能,并且均能够提供Lazy Load Route的特性。如果我们能够通过某种手段欺骗单页应用的框架,让他能够拿到拆分过的Lazy Load Route文件,进而去加载对应页面,那么我们就可以做到无需应用框架重启,便可以加载不同业务。

那么我们可以通过Nginx的反向代理功能,让应用能够顺利拿到对应路由的代码,此方案的关键在于如何确保共有代码绝对一致,从而保证框架能够一直认为其为一个完整的应用。

Dynamic Router Loading 架构示例图.png

自然可以得出,我们必须保证开发中加入一些限制条件,才能保证本方案能够被顺利执行。

  1. 每个工程必须拥有所有业务的全量路由表:因为既然在浏览器上需要保证为一个单页应用的形式,那么应用必须知道所有应用的路由,才能正确地加载应用。
  2. 公同依赖(包含各个业务开发中没有抽离到初始化代码中,但是都会使用的依赖,比如lodash)需要一致:应用需要能被正确执行,那么就必须保证页面切换中,页面中所有部分的代码都是基于同一套基础依赖的,不然就无法保证应用能够被正确执行,比如A,B站需要互相无刷新页面切换,A站使用React开发,B站使用Angular开发,两天路由加载的逻辑根本的不同,你无法使用React的路由去加载Angular的路由代码,反之亦然。当然在实践执行中,你即便使用的同一套框架,很多细节的代码也必须保持一致才能保持整个大应用能准确无误的被执行。

凡事必有代价,这个方案在我们实践中也带来了不少问题。

你别看上面两项限制看起来简单,但是因为我们的基本思路是基于某个现有的前端框架,然后将不同站点通过Nginx等代理软件,伪装成同一个单页应用的一部分来提示用户体验。不同业务必须要保证其均能够运行在同一套代码上下文下,这本身就是本末倒置,之前方案一的出发点就是为了解耦应用,让业务开发者不需要了解其他团队怎么开发,只需要保证符合业务需求即可。但是此方案导致:

  1. 开发者必须使用同样的开发框架,本身就和微服务的开发框架选项无关性背道而驰。
  2. 因为应用运行在同一套框架执行上下文上,而开发者团队又是在独立开发和部署的开发模式下。必然导致线上线下环境的割裂,很多联调的问题只会在上线部署配置完成后,一些执行上下文的细微区别的影响才有可能会被暴露出来,轻则业务切换B后应用行为和单独访问B的时候不一致,重则加载B站会导致应用崩溃。

这个方案下,由于环境的割裂,业务开发者又不可能去了解整个应用的开发进展,必然导致很多错误会被推出到上线,而排错又需要了解整个运行原理和所有团队的开发进展,导致排错困难。错误又难以在上线前排查出来。

这个方案而言,我们又进一步做了一些优化方案,其中比较好的方案是将公共依赖尽可能的抽出成为CDN,并且我们保证CDN上的版本总是最新的版本,这样很多依赖版本导致的问题可以结合一些开发部署策略尽可能避免,这样基本能够被应用起来,但不得不说,离真正的前端微服务而言,还有很长的路。

Other Solution Idea

还有其他的一些解决思路,可以参考下这篇文章Building Microfrontends,其中最有希望的是Web Component方案,不过这个方案基于浏览器标准的实现,而且每个组件部分其实完整的应用,可能会引入一定的代码冗余,但是是能满足我们在独立部署下不刷新切换页面愿景的,而且解耦的粒度更下,是页面上的组件级别,是相对有潜力的一个方案。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 156,265评论 4 359
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 66,274评论 1 288
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 106,087评论 0 237
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,479评论 0 203
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 51,782评论 3 285
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,218评论 1 207
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,594评论 2 309
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,316评论 0 194
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 33,955评论 1 237
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,274评论 2 240
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 31,803评论 1 255
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,177评论 2 250
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 32,732评论 3 229
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 25,953评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,687评论 0 192
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,263评论 2 267
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,189评论 2 258

推荐阅读更多精彩内容