字节跳动是如何落地微前端的

微前端的出现的背景和意义

微前端是什么:微前端是一种类似于微服务的架构,是一种由独立交付的多个前端应用组成整体的架构风格,将前端应用分解成一些更小、更简单的能够独立开发、测试、部署的应用,而在用户看来仍然是内聚的单个产品。
微前端诞生在两个大的背景下,在提倡拥抱变化的前端社区可以看到新的框架、技术、概念层出不穷,并且随着 Web 标准的演进,前端应用已经具备更好的性能、更快的开发效率。但随着而来的是应用的复杂程度更高、涉及的团队规模更广、更高的性能要求,应用复杂度已经成为阻塞业务发展的重要瓶颈。
微前端就是诞生于 Web 应用日益复杂化的场景中,因为随着网络速度、计算机硬件水平的提升和 Web 标准的演进,过去 Web 应用用户体验远不如传统的应用软件时代已逐渐远去,两者之间在用户体验上的差距不断缩减,并且由于 Web 应用开发速度快、用完即走等特性,导致的一个最终结果就是「能用 Web 技术实现的应用,最终都会通过 Web 来实现」。在近几年涌现了一大批之前只能在传统 PC 软件中才能看到的优秀产品,例如:Photoshop、Web Office、Web IDE。尽管随着 Web 标准的演进,前端工程化也在不断演变,从模块化到组件化在到现在的工程化,但在面对跨团队大规模开发、跨团队企业级应用协作,现有的分治设计模式仍然显得有心无力。

大规模 Web 应用的困局
尽管 Web 应用的复杂度和参与人数以爆炸式的增长速度,但却没有一种新的架构模式来解决现有的困境,并同时兼顾 DX(developer experience)和 UX(user experience)。
以字节跳动内「研发中台」举例,在研发日常工作中需要使用非常多的研发系统,例如:代码管理、代码构建、域名管理、应用发布、CDN 资源管理、对象存储等。站在整个公司研发的角度考虑,最好的产品形态就是将所有的研发系统都放置同一个产品内,用户是无法感知他在使用不同的产品,对于用户而言就是单个产品不存割裂感,也不需要去学习多个平台,仅仅需要学习和了解字节跳动内的「研发中台」即可。
在字节跳动内这一类应用随处可见,由于字节跳动内存在大量业务线,每一条业务线都会诞生大量的中台系统,并且还在指数增长,以字节跳动内电商业务举例,对于电商运营的日常工作来说,其实与研发日常工作一样,围绕在:商品、商家、品牌、风控、营销等工作上,那么对于电商运营来说怎么样才最高效的电商运营系统呢,由于整个系统涉及范围较广,在实际的研发过程中必然会以功能或业务需求垂直的切分成更小的子系统,切分成各种小系统后尽管由于分治的设计理念提升了开发者体验,但是一定程度上降低了用户体验。那能否以一种新的架构模式,既保开发者体验,又能提升用户体验呢。
传统 Web 应用的利与弊
这里简单分析一下传统 Web 应用在开发大规模应用和涉及多研发团队协作时遇到的一些困境,以上面案例中的「电商运营平台」举例,对于电商运营而言商品、商家、品牌等都是电商运营平台能力的一部分,而不是独立之间的孤岛。若以传统的前端研发模式进行开发,那么此时有两种项目设计策略:

将平台内多个系统放置同一个代码仓库维护 ,采用 SPA(Single-page Application) 单页应用模式
将系统分为多个仓库维护,在首页聚合所有平台的入口,采用 MPA(Multi-page Application)多页应用模式

若采用多个系统放置同一个项目内维护:

优势:

更好的性能

具备局部更新,无缝的用户体验

提前预加载用户下一页的内容

统一的权限管控、统一的 Open API 开发能力

更好的代码复用,基础库复用

统一的运营管理能力

不同系统可以很好的通信

SPA 应用特有优势

劣势:

代码权限管控问题

项目构建时间长

需求发布相互阻塞

代码 commit 混乱、分支混乱

技术体系要求统一

无法同时灰度多条产品功能

代码回滚相互影响

错误监控无法细粒度拆分

采用方案一的劣势非常明显,在日常开发中研发:代码构建半小时以上、发布需求时被需求阻塞、无法局部灰度局部升级、项目遇到问题时回滚影响其他业务、无法快速引进新的技术体系提高生产力,项目的迭代和维护对于研发同学而言无疑是噩梦。
尽管降低了开发体验,如果对项目整体的代码拆分,懒加载控制得当,其实对于使用平台的用户而言体验却是提升的,这一切都归咎于 SPA 应用带来的优势,SPA 应用跳转页面时无需刷新整个页面,路由变化时仅更新局部,不用让用户产生在 MPA 应用切换时整个页面刷新带来的抖动感而降低体验,并且由于页面不刷新的特性可以极大程度的复用页面间的资源,降低切换页面时带来的性能损耗,用户也不会感知他在使用不同平台。

若采用拆分成多个仓库维护

优势

可以以项目维度拆分代码,解决权限管控问题

仅构建本项目代码,构建速度快

可以使用不同的技术体系

不存在同一个仓库维护时的 commit 混乱和分支混乱等问题

功能灰度互不影响

劣势

用户在使用时体验割裂,会在不同平台间跳转,无法达到 SPA 应用带来的用户体验

只能以页面维度拆分,无法拆分至区块部分,只能以业务为维度划分

多系统同灰度策略困难

公共包基础库重复加载

不同系统间不可以直接通信

公共部分只能每个系统独立实现,同一运维通知困难

产品权限无法进行统一收敛

采用方案二在一定程度上提升了开发体验,但却降低了用户体验,研发在日常开发工作中需要使用大量的平台,但是却需要跳转到不同的平台上进行日常的研发工作,整体使用体验较差。体验较差的原因在于将由于通过项目维度拆分了整体「研发中台」这样的一个产品,使各个产品之间是独立的孤岛,系统间相互跳转都是传统意义上的 MPA,跳转需要重新加载整个页面的资源,除了性能是远不如 SPA 应用的并且应用间是没法直接通信,这就进一步增强了用户在使用产品时的割裂感。
背景和意义总结
通过以上两个场景案例,其实可以发现由于 Web 应用在逐步取代传统的 PC 软件时,大规模 Web 应用在面对高复杂度和涉及团队成员广下无法同时保证 DX 和 UX 的困境。传统的分而治之的策略已经无法应对现代 Web 应用的复杂性,因此衍生出了微前端这样一种新的架构模式,与后端微服务相同,它同样是延续了分而治之的设计模式,不过却以全新的方法来实现。
微前端解决方案
上一节总结了微前端出现的背景和意义,并且了解了两种传统 Web 应用的研发模式:SPA(Single-page Application)、MPA(Multi-page Application)在涉及人员广和项目复杂度高的场景下带来的劣势,那么期望能有一种新的架构能同时具备 SPA 和 MPA 两种架构优势,并同时提升 DX(developer experience)和 UX(user experience)呢?
那在理想的情况下,期望能达到,将一个复杂的单体应用以功能或业务需求垂直的切分成更小的子系统,并且能够达到以下能力:

子系统间的开发、发布从空间上完成隔离
子系统可以使用不同的技术体系
子系统间可以完成基础库的代码复用
子系统间可以快速完成通信
子系统间需求迭代互不阻塞
子应用可以增量升级
子系统可以走向同一个灰度版本控制
提供集中子系统权限管控
用户使用体验整个系统是一个单一的产品,而不是彼此的孤岛
项目的监控可以细化到到子系统

那么基于上面理想情况,如何从零设计一套全新的架构用于解决现代 Web 应用在面对企业级系统遇到的困境呢。

你可能感兴趣的