2025-01-22
10 min read

微前端

微前端是什么:微前端是一种类似于微服务的架构,是一种由独立交付的多个前端应用组成整体的架构风格,将前端应用分解成一些更小、更简单的能够独立开发、测试、部署的应用,而在用户看来仍然是内聚的单个产品

传统web应用利与弊

传统 Web 应用在开发大规模应用和涉及多研发团队协作时遇到的一些困境,以电商平台举例,对于电商运营的商品、营销、物流、售后等都是电商平台能力的一部分,若以传统的前端研发模式进行开发,可以有以下两种策略

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

多个系统放置同一个仓库维护优缺点

优势

  • 更好的性能
  • 具备局部更新、无缝的用户体验
  • 提前预加载用户的下一页内容
  • 统一的权限管理、统一的open api开发能力
  • 更好的代码复用、基础库的服用
  • 统一的运营管理能力
  • 不同系统可以很好的通信
  • SPA应用的特有优势

缺点

  • 代码权限管控问题
  • 项目构建时间问题
  • 需求发布相互阻塞
  • 代码commit、分支管理混乱
  • 技术体系要求统一
  • 无法同时灰度多条产品功能
  • 代码回滚问题
  • 错误监控细分问题

此方案劣势一目了然:在日常开发中研发:代码构建半小时以上、发布需求时被需求阻塞、无法局部灰度局部升级、项目遇到问题时回滚影响其他业务、无法快速引进新的技术体系提高生产力,项目的迭代和维护对于研发同学而言无疑是噩梦

尽管降低了开发体验,如果对项目整体的代码拆分,懒加载控制得当,其实对于使用平台的用户而言体验却是提升的,这一切都归咎于 SPA 应用带来的优势,SPA 应用跳转页面时无需刷新整个页面,路由变化时仅更新局部,不用让用户产生在 MPA 应用切换时整个页面刷新带来的抖动感而降低体验,并且由于页面不刷新的特性可以极大程度的复用页面间的资源,降低切换页面时带来的性能损耗,用户也不会感知他在使用不同平台

采用拆分成多个仓库维护

优势

  • 可以以项目纬度拆分代码,解决权限管控问题
  • 仅构建本项目代码,速度快
  • 可以使用不同的技术体系
  • 不存在同一个仓库维护时commit混乱和分支混乱问题
  • 功能灰度互不影响

劣势

  • 用户在使用时体验割裂,会在不同平台间跳转,无法达到spa应用带来的用户体验
  • 只能以页面纬度拆分,无法拆分至区块部分,只能以业务为维度划分
  • 多系统同灰度策略困难
  • 公共包基础库重复加载
  • 不同系统间不可以直接通信
  • 公共部分只能每个系统独立实现,同一运维通知困难
  • 产品权限无法进行统一收敛

此方案开发体验上有一定程度的提升,但却降低了用户体验,研发在日常开发工作中需要使用大量的平台,但是却需要跳转到不同的平台上进行日常的研发工作,整体使用体验较差

体验较差的原因在于将由于通过项目维度拆分了整体「研发中台」这样的一个产品,使各个产品之间是独立的孤岛,系统间相互跳转都是传统意义上的 MPA,跳转需要重新加载整个页面的资源,除了性能是远不如 SPA 应用的并且应用间是没法直接通信,这就进一步增强了用户在使用产品时的割裂感

微前端解决方案

理想的情况下,期望能达到,将一个复杂的单体应用以功能或业务需求垂直的切分成更小的子系统,并且能够达到以下能力

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

整体架构

为什么不是iframe

谈到微前端绕不开的话题就是为什么不适用 iframe 作为承载微前端子应用的容器,其实从浏览器原生的方案来说,iframe 不从体验角度上来看几乎是最可靠的微前端方案了,主应用通过iframe 来加载子应用,iframe 自带的样式、环境隔离机制使得它具备天然的沙盒机制,但也是由于它的隔离性导致其并不适合作为加载子应用的加载器,iframe 的特性不仅会导致用户体验的下降,也会在研发在日常工作中造成较多困扰,以下总结了 iframe 作为子应用的一些劣势

  • 使用iframe会大幅增加内存占用和计算资源,因为iframe内所承载的页面需要一个全新并且完整的文档环境
  • iframe与上层应用并非同一个文档上下文
  • 事件无法冒泡顶层,针对整个应用统一处理时效
  • 事件冒泡不穿透到主文档树上,焦点在子应用时,事件无法传递上一个文档流
  • 跳转路径无法与上层文档同步,刷新丢失路由状态
  • iframe 内元素会被限制在文档树中,视窗宽高限制问题
  • iframe 登录态无法共享,子应用需要重新登录
  • iframe 在禁用三方 cookie 时,iframe 平台服务不可用
  • iframe 应用加载失败,内容发生错误主应用无法感知
  • 难以计算出 iframe 作为页面一部分时的性能情况
  • 无法预加载缓存 iframe 内容
  • 无法共享基础库进一步减少包体积
  • 事件通信繁琐且限制多

基于 SPA 的微前端架构

设计层面采取的是基座+子应用分治的概念,部署平台负责进行服务发现和服务注册,将注册的应用列表信息下发至基座,通过基座来动态控制子系统的渲染和销毁,并提供集中式的模式来完成应用间的通信和应用的公共依赖管理