微前端运行时

微前端运行时

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

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

基于 SPA 的微前端架构

尽管难以将 Iframe 作为微前端应用的加载器,但是却可以参考其设计思想,一个传统的 Iframe 加载文档的能力可以分为四层:文档的加载能力、HTML 的渲染、执行 JavaScript、隔离样式和 JavaScript 运行环境。那么微前端库的基础能力也可以参考其设计思想。

从设计层面采取的是基座+子应用分治的概念,部署平台负责进行服务发现和服务注册,将注册的应用列表信息下发至基座,通过基座来动态控制子系统的渲染和销毁,并提供集中式的模式来完成应用间的通信和应用的公共依赖管理,因此 Garfish 在 Runtime 层面主要提供了以下四个核心能力:
加载器(Loader)

  • 负责注册平台侧提供的应用列表
  • 负责加载和解析子应用入口资源
  • HTML 入口类型,拆解 HTML Dom、Script、Style
  • JS 入口类型,提供基础 Dom 容器
  • 预加载能力
  • 解析子应用导出内容

沙箱隔离(Sandbox)

  • 提供代码执行能力,收集执行代码时存在的副作用
  • 提供销毁收集副作用的能力
  • 支持沙箱多实例,收集不同实例的副作用

路由托管(Router)

  • 解决不同应用间的路由不同步问题
  • 提供路由劫持能力,在主应用上管控子应用路由
  • 提供路由驱动能力来拼装完整的平台的能力

子应用通信(Store)

  • 建立通信桥梁
  • 提供共享机制

应用生命周期

整个微前端子应用的生命周期基本可以总结为:
渲染阶段

  • 主应用通过路由驱动或手动挂载的方式触发子应用渲染
  • 开始加载应用的资源内容,并初始化子应用的沙箱运行时环境
  • 判断入口类型
    • 若入口类型为 HTML 类型,将开始解析和拆解子应用资源
    • 若入口类型为 JS,创建子应用的挂点 DOM
  • 将子应用存在”副作用“(对当前页面可能产生影响的内容)交由沙箱处理
  • 开始渲染子应用的 DOM 树
  • 触发子应用的渲染 Hook

销毁阶段

  • 若路由变化离开子应用的激活范围或主动触发销毁函数,触发应用的销毁
  • 清除应用在渲染时和运行时产生的副作用
  • 移除子应用的 DOM 元素

猜你喜欢

转载自blog.csdn.net/zz130428/article/details/130260000
今日推荐