上微前端后,我司的祖传代码有救了

上微前端后,我司的祖传代码有救了
2021年01月19日 08:30 InfoQ

在 2021 年说起微前端,已不像前几年那么让人迷茫。越来越多的互联网公司正在将它应用到自身的重要业务中。爱奇艺号也开发了一套微前端架构,成功在开发环境中将代码热更新的速度提升了 90% 以上。为了解微前端在实践中的更多真实收益,近日,我们采访了爱奇艺资深前端工程师杨昊一,他在 QCon+ 案例研习社分享了题为《爱奇艺号微前端从零到一架构实践》的演讲。

前端圈子永远不乏新概念。几年前提起微前端,还会有一大把的人问这是什么意思,惊讶于前端和微服务竟然能产生联系。而在今天,微前端绝对是前端界的一个热词。有的团队在生产环境中实践它,有的团队抽象出了内核开源了它的框架,还有些团队听说它的种种好处跃跃欲试。

在爱奇艺号近几年快速发展的过程中,他们意识到了一些问题——现代流行的前端框架在部署时都会将所有的依赖统一打包,而在业务急速扩展时,包的大小也会急速膨胀,导致上线效率越来越差,更不用说开发时的各种代码冲突、不同团队间的合作开发问题了,于是他们开发了一套微前端架构,并且成功应用到了多个重要业务中。每次都重新部署主应用,极大地提高了上线效率。甚至在开发环境中代码热更新的速度都能提升 90% 以上。近日,我们采访了爱奇艺资深前端工程师杨昊一老师,了解到更多微前端在爱奇艺号的落地情况。

微前端到底是什么

 InfoQ:有人说,微前端这个概念是由后端引入的,你怎么看?

杨昊一: 微前端其实是现代前端框架发展到一定程度时自然产生的一个方案,不能说完全是由后端引入的。只不过是恰巧世界上解决这类问题的大方法殊途同归,借鉴了后端微服务的一些理念应用到了前端,成为了微前端。在微前端之前,前端并没有类似的理念或者代码框架,可能不能算是大家理解的那种重复写代码的那种造轮子。但是我理解是借鉴了后端微服务这个轮子,加以改进优化,应用到了前端框架上,提升了现代前端框架很多方面的体验。

 InfoQ:什么样的业务需要用到微前端?这些场景真的有必要用微前端吗?

杨昊一: 我一直觉得使用什么技术一定要用最适合自己的,不能仅仅因为微前端很火就强行给自己的项目上这个技术。我们应用微前端技术是因为业务发展到了一定程度很自然的就想到需要用微前端来解决各种代码开发、项目需求的问题。再比如那种需要很模块化组装页面的网站也就非常适合使用微前端。但是如果是复杂度不高的一个项目,比如一个公司的官网、一个博物馆的网站,非要使用微前端反而会造成复杂度上升、维护性下降。

 InfoQ:引入微前端需要天时地利人和,请从引入时机、自身的资源条件、人员三个方向对此做出解析。

杨昊一: 我觉得在项目开始的时候就需要对今后的发展进行一些预判。如果第一开始判断这个项目今后会非常复杂,比如可能会接入十几个业务、多个团队一起维护等情况,在开头就可以引入微前端,这样能够极大减少今后重构的成本。如果说错过了开始阶段的布局,在业务发展的时候意识到需要使用微前端框架了,也要尽早对主框架进行微前端化,不能任由情况恶化,否则之后可能会花比现在多几倍的时间去重构。因为我们自己做的微前端框架算是一种现有框架的超集,100% 兼容传统的开发方式,所以我们可以在不影响现有需求开发的情况下一部分一部分地对老代码进行更新。

大家也可以发现应用微前端概念最多的还是体量达到一定程度的公司和项目,因为现代的 SPA 框架在业务发展到一定程度时一般都会出现代码库巨大、部署时间久的问题,而微前端解决的一个重点问题就是这个。这些公司一般都有意愿进行新的架构探索以便提升自身的开发效率,如果现有的开发方式并不会影响到开发效率时就不需要使用微前端了。

同样,微前端重点解决的还有多个团队维护代码耦合的问题。小型项目可能很难出现多个团队的情况,所以当你觉得不需要微前端的时候就不要强行使用它。

所以,在业务开发时如果觉得现有的开发方式、框架不会影响你的开发效率,那就说明你的框架并不需要进行微前端化。就像以前描述什么时候用 Redux 时很有名的话:“如果你不知道是否需要 Redux,那就是不需要它。”这个时候就不能因为微前端很火而强行应用它,很多时候可能会发现用了微前端反而不如以前开发那么行云流水了。

选择适合自己的微前端方案

 InfoQ:目前业界有哪些微前端方案,他们分别有什么优缺点?

杨昊一: 其实微前端有很多种实现方案,比如 iframe 其实就是一种很古老但是有些时候很有用的一种实现方法。它有纯天然的隔离机制、兼容性最广,但是在各个环节的通讯上有很大的不足,性能和用户体验上也做不到很好。

现在最流行的微前端还是在各个框架之上设计一套加载机制,像在 Vue、React 等框架上面再加一层自己的通讯、页面加载的方法实现不同框架之间自由切换的功能。大家听过最多的可能就是 single-spa 了,很多大型项目多多少少都使用了这个框架。使用这类框架一般能够体验到最现代化的前端开发方法,但是在老式浏览器上兼容性可能不是那么的好。single-spa 算是一套比较成熟的微前端框架了,但是并不代表使用它就是一件简单的事,毕竟微前端就是一种比较高级的前端开发模式。

选择框架时绝对不要做 100% 拿来主义,没有任何一个框架是天生绝对适合自己的,其实很多使用了 single-spa 的项目都是进行了魔改来最大程度契合自己项目的需求的。

 InfoQ:爱奇艺号是什么时候开始做微前端的?你们的微前端方案是什么样的?为什么选择这个方案?请介绍一下你们的设计过程中的考量。

杨昊一: 爱奇艺号在 2017 年的时候就进行过一些微模块化的探索,但是实际应用到生产环境则是 2019 年了,因为代码体积、业务增长、团队细分化等原因开始在一部分业务上使用了微前端。就像上面我提到过的,我们使用微前端技术是项目发展到一定程度水到渠成的事儿。

我们的大框架是基于 Vue 的,并不涉及到需要使用另一种前端框架的情况(比如 React)。我们还希望做的微前端框架能够 100% 兼容现有的开发方法,也就是说开发新需求的时候用不用微前端随意。并且我们不希望主框架依赖太多第三方的代码,所以我们并没有使用任何第三方微前端框架,而是在我们现有的主框架下按照微前端的开发理念直接手写增加了一套微前端的逻辑。我们的框架完全是基于 Vue 增加了一个微前端的功能,这个功能也不是很复杂,所以可能对单纯使用 Vue 不希望增加任何其他全家桶框架的团队很有吸引力。虽然我们是基于 Vue 的,但是因为微前端基本原理纯天然的就对任何其他代码友好,我们的框架也能实现在 Vue 上加载一个 React 页面。

我们的子模块是按照业务、功能同时来区分的。我们大部分微前端模块都各自代表了一个业务,有单独的路由配置,这样各个业务团队就不需要去碰主框架改路由了。当然,如果一个业务体量巨大,每一个功能都是一个特别复杂的整体的时候,就需要按照功能块来区分,比如数据分析就作为一个单独的模块来构建。

其实微前端的基本逻辑并不是很复杂,最基本的就是做到路由能够正确获取到该加载的模块代码并且将其解析渲染。在主框架下的 app.js 部分、路由解析部分增加这块逻辑也不会涉及到框架大改造,使用第三方的框架则会多少涉及到大框架改造,需要花不少的时间和人力,也会和业务发展的快速迭代冲突。

 InfoQ:你们现在微前端的规模是怎样的?下一步将如何演进?

杨昊一: 我们已经在很多业务和功能上应用了微前端,我们也在持续的进行架构优化,基本上我们每轮开发都会多少上线一些框架优化。但是因为我们的微前端框架开始于一个本身体量超大的项目(比如在我的 i7 7700H 笔记本上打包需要至少 150 秒……),下一步我们肯定是要实现主框架与全部业务逻辑彻底解耦,实现整体微前端化,这也会极大提升我们业务开发的效率。我们也会持续不断地提升页面加载的速度、适当预加载等各种方面的优化。

不吹不黑,谈谈微前端的得与失

 InfoQ:能否谈谈上微前端之后的真实收益?

杨昊一: 我们的项目代码原本有多个团队共同维护,尽管业务逻辑已经拆分开,但是代码的祖先都是我们刚开始只有一个团队时候开发的,所以耦合很严重,偶尔就会有一些代码冲突。上线微前端以后我们优先对其他团队的模块进行了解耦,直到从 package.json 里移除了那个项目依赖。这样我们就再也不用担心他们在我们的代码库里做了什么可能导致问题的改动。

在改造模块的时候,我们也对其进行了业务上的梳理,功能定义更加清晰,也提升了今后我们业务上开发的效率。对拥有古老代码的项目进行微前端化也是一个不错的重构的机会!

 InfoQ:对于开发人员,有哪些开发体验上的提升?

杨昊一: 作为开发人员,我们最直接的感觉就是上线方便了很多。以前哪怕改一处文案都需要等差不多半个小时把主框架上线一遍,现在我们仅需要花 2、3 分钟上线子模块就好。这样也能极大的提高一些线上问题的修复速度。

提到速度,对我们本地开发效率也提升很大。改造之前本机冷启动项目就需要 2、3 分钟启动。改造以后我们可以选择冷启动时需要启动的模块,不需要的就不进行打包编译。比如我们在做数据分析相关的页面时,就不需要启动发布视频的功能模块了。还有热更新,改造前每当改动一行代码,热更新就需要 10 秒。在改造后,因为每个微前端模块是单独打包编译的,热更新只需要零点几秒即可完成。

其次,我们的微前端框架也做到了页面模块化配置,通过配置文件就可以把很多模块拼成一个页面。每个小模块的功能更加清晰明了。

 InfoQ:微前端的工程化与传统前端工程化有哪些不同?

杨昊一: 微前端在我看来只是基于现代的前端工程化的一个进化。在大型项目中传统的前端工程化有时会造成臃肿、不易维护的代码库,降低开发效率,也会降低自动化部署的效率,而这也违背了工程化提升开发效率的初衷。

传统前端工程化是为了解决古老的前端从 Page 转变为 App 的这种复杂工程问题产生的解决方案。经过了这么些年的发展,其产生了一些新的问题,微前端就是解决这些问题的优化方案,通过化整为零,提升组件化、模块化、自动化的效率,让多个团队可以更加和谐地维护同一个项目。也许过了几年,随着前端技术的发展微前端也会出现一些新的问题,到时候可能就会有顺应时代的新技术来解决微前端的问题了。

 InfoQ:目前还有哪些亟待解决的问题?对于一些复杂场景,微前端是否会导致维护起来比较困难?

杨昊一: 其实经过了几年的发展,微前端框架现在已经算较为成熟了,基本的问题都有了解决方法。但是有了解决方法并不代表这个方法是完美的,有一些问题仍然在持续进行探索,比如微前端沙盒的问题,现在也并没有一个能够特别完美实现的方案。还有微前端多多少少会造成一些性能的损失,这个只能靠各个研发人员持续不断地研究才能不断地进步。

一个好的微前端项目是需要一个合理的规划的,不能把模块拆得太细也不能太粗,要按照实际的需求进行规划才能最大提升后期的维护成本。其实不管是不是用微前端,复杂的场景维护都比较复杂,微前端在我们看来反而是能够减少一些维护难度的。

 InfoQ:对微服务来说,运维是一个痛点,微前端作为微服务在前端领域的变体,在服务治理和运维也有类似的难题,你们是怎么做的?

杨昊一: 把一个大项目分拆为各个微前端服务,合理的分配模块拆分细度是很重要的。我们的页面都会尽量做到不出现多层引入微模块的问题,比如页面中只加载模块 1、2、3,不出现模块 1 中再加载模块 2、3,这样就能减少因为调用链变长导致的复杂情况。同时这样也会避免一个模块坏掉导致后面一串儿的模块都出问题的情况。

探索更长远的价值

 InfoQ:以上我们谈论的东西都是微前端在工程上的价值,而工程最终是要为业务服务的。如果要一个公司花大力气去推进这件事情,那它应该是要能推动业务提升,你认为微前端对业务有哪些作用?

杨昊一: 当一个业务体量达到一定程度时,就需要细分业务,由不同的团队专门负责某一部分的业务。这个时候微前端就能够让团队有独立迭代的能力,也能够很轻松的围绕着业务来打造团队,而不用同时维护基础框架还要进行业务代码开发。一个大型技术团队利用了微前端可以有一个基础框架团队和多个业务团队,提升业务开发效率,同时也可以保证不同业务之间的页面体验一致。

在越大的公司和项目下,微前端对业务的价值一般也就越大了。

 InfoQ:现在业界都在探索微前端,还没有形成一个统一的标准,各家都有自己的方案。更长远的看,你认为这个标准会出现吗?在你的设想中,一个标准的微前端技术体系应该是怎样的?

杨昊一: 微前端作为一种前端工程化的方法,原理其实并不是很复杂,各家现在有不同的方案,但是底层原理都是相同的。从实现方法来讲今后也许也不会有一个统一的标准,但是可能会出现几种大家都认可的方案。可能是一种更大认可度的方案 + 几个其他的方案,就像 Webpack、NPM 在业界的地位;也可能是几个不相上下的方案,像 Vue、React、Angular 等各自的地位一样。

一个标准的微前端技术体系,要包含合理的路由分治方案,能够正确的远程获取并解析页面的路由;页面要做到高性能的微前端模块渲染;各个模块要做到代码不耦合;主框架与微前端模块彻底分离。

采访嘉宾

杨昊一,爱奇艺资深前端工程师,2017 年加入爱奇艺,目前负责爱奇艺号前端架构体系升级建设。在前端应用架构、开发流程规范等方面有丰富实践经验。2013 年硕士毕业于 University of Michigan - Ann Arbor,加入爱奇艺前曾就职于美国 Yahoo! 主站前端部门,负责雅虎新闻、体育等项目研发及架构更新工作。

财经自媒体联盟更多自媒体作者

新浪首页 语音播报 相关新闻 返回顶部