基于 iframe 的微前端框架

简介: 一、背景VAPD是一款专为团队协作办公场景设计的项目管理工具,实践敏捷开发与持续交付,以「项目」为核心,融合需求、任务、缺陷等应用,使用敏捷迭代、小步快跑的方式进行开发及质量跟踪,简化工作流程,帮助团队快速迭代并高效完成产品开发交付。但早期VAPD以“一切皆可配置”的设计理念开发运行了两年,整个前端代码复杂混乱,组件庞大(需要支持多种配置),状态混乱,前端代码打包出来有50M之巨。这个项目难以为继,bug多、维护困难、新增功能处处受限,总之产品不满意、测试不满意、用户不满意。因此改版是必然的选择,而改版的要求就是不能耽误用户继续使用,必须保证网站可用、逐步更新,因此微前端是必然的

一、背景

VAPD是一款专为团队协作办公场景设计的项目管理工具,实践敏捷开发与持续交付,以「项目」为核心,融合需求、任务、缺陷等应用,使用敏捷迭代、小步快跑的方式进行开发及质量跟踪,简化工作流程,帮助团队快速迭代并高效完成产品开发交付。

但早期VAPD以“一切皆可配置”的设计理念开发运行了两年,整个前端代码复杂混乱,组件庞大(需要支持多种配置),状态混乱,前端代码打包出来有50M之巨。这个项目难以为继,bug多、维护困难、新增功能处处受限,总之产品不满意、测试不满意、用户不满意。

因此改版是必然的选择,而改版的要求就是不能耽误用户继续使用,必须保证网站可用、逐步更新,因此微前端是必然的选择。

VAPD改版思路就是:

  1. 使用微前端框架,未改版部分作为子应用存在,继续为用户服务;
  2. 将项目模块制定系统应用,并逐个改版,降低项目复杂度;
  3. 逐步舍弃旧项目代码,将功能转移到新项目中,提升项目整体性能,提高代码可维护性。

二、什么是微前端

Techniques, strategies and recipes for building a modern web app with multiple teams that can ship features independently. —— Micro Frontends.

微前端是一种多个团队通过独立发布功能的方式来共同构建现代化 web 应用的技术手段及方法策略。

微前端将微服务的理念应用于浏览器端,即将单页面前端应用由单一的单体应用转变为把多个小型前端应用聚合为一的应用,各个前端应用独立开发、独立部署。

微前端架构旨在解决单体应用在一个相对长的时间跨度下,由于参与的人员、团队的增多、变迁,从一个普通应用演变成一个巨石应用(Frontend Monolith)后,随之而来的应用不可维护的问题。这类问题在企业级 Web 应用中尤其常见。

现行最出名的微前端是阿里的qiankun,qiankun 是一个基于 single-spa 的微前端实现库,旨在帮助大家能更简单、无痛的构建一个生产可用微前端架构系统。

但我尝试试用qiankun后发现qiankun 的npm包常常滞后于qiankun源码,有些issue解决了但还要等待其发版;首次加载子应用页面出现抖动;子应用更新后报 ChunkLoadError 问题 。

同时它存在微前端框架常有的性能问题及冲突问题:

1、加载慢

基本上所有的微前端框架都需要先加载父框架,再加载子应用,都要经历如下图的流程。整个流程是串行的,相同流程需要走两遍,也就比普通的非微前端框架要慢1倍左右,直接影响了用户体验。

2、切换慢,每次切换都要重新走一次流程

微前端框架中不同子应用切换,需要销毁当前子应用,然后加载其他子应用。子应用又需要进行“下载html --> 下载javascript文件 --> 运行javascript代码 --> 请求服务端数据 --> 页面展示"整个流程,导致微前端框架切换应用卡顿不流畅。

3、容易出现样式冲突,不同子应用容易影响

传统微前端框架中所有子应用都在同一上下文中,如出现全局样式、全局监听、全局变量,便会对其他子应用有影响,容易出现样式冲突,内存泄漏,或者不可预知的bug。

三、Why Not Iframe

iframe 最大的特性就是提供了浏览器原生的硬隔离方案,不论是样式隔离、JS隔离这类问题统统都能被完美解决。

那为啥不使用iframe呢?

qiankun 团队也给出了原因:看这里 Why Not Iframe。

总结起来就是:

  • url 不同步。浏览器刷新 iframe url 状态丢失、后退前进按钮无法使用。
  • UI 不同步,DOM 结构不共享。想象一下屏幕右下角 1/4 的 iframe 里来一个带遮罩层的弹框,同时我们要求这个弹框要浏览器居中显示,还要浏览器 resize 时自动居中..
  • 全局上下文完全隔离,内存变量不共享。iframe 内外系统的通信、数据同步等需求,主应用的 cookie 要透传到根域名都不同的子应用中实现免登效果。
  • 慢。每次子应用进入都是一次浏览器上下文重建、资源重新加载的过程。

其中有的问题比较好解决(问题1),有的问题我们可以睁一只眼闭一只眼(问题4),但有的问题我们则很难解决(问题3)甚至无法解决(问题2),而这些无法解决的问题恰恰又会给产品带来非常严重的体验问题, 最终导致我们舍弃了 iframe 方案。

四、擎天框架设计

4.1 设计理论

基于以上微前端缺陷,设计新型的微前端框架需要满足以下要求:

  • —— 页面加载速度、应用切换速度是前端极致的追求,用户操作的响应速度永远是第一体验。
  • 完全隔离 —— 不同子应用完全隔离,只在子应用项目初始化时设置一次,之后不需要在后续开发中及后期维护中考虑,降低开发的心智负担。

4.2 架构设计

擎天框架架构分为三层,分别是用户入口(浏览器地址栏),主应用层以及子应用集合层。

(1)浏览器(地址栏)是用户入口,用户通过输入URL进入该系统,同时浏览器地址栏URL根据应用页面进行变化,方便用户复制分享二次进入。

(2)主应用是擎天框架的关键部分,主要是由以下两部分组成:

  • 路由引擎:实现浏览器地址栏与子应用展示隐藏的协调控制,用来控制用户第一次进入展示某个应用,当用户切换页面时需同步浏览器地址栏(方便用户复制,再次进入同一页面),并根据页面URL展示隐藏子应用。
  • 数据共享引擎:实现子应用间的数据共享,保证各个应用间数据统一,如登录信息,用户信息等。用户在某个应用修改共享数据后,会同步到数据共享引擎,再分发给其他应用,从而保证共享数据一致。

(3)子应用集合层

该层为系统提前设置好的子应用集合,子应用由全屏iframe加载,同一时刻仅有一个子应用处于可视状态,其他子应用隐藏。当需要应用切换时,隐藏当前应用,显示需要展示的应用,瞬间切换。

子应用响应擎天的路由引擎及数据共享引擎,做到实时的路由同步与数据同步,保证整个微前端项目路由及数据统一。

五、擎天框架实现

擎天框架突破了 iframe UI不同步、URL不同步、数据不共享以及加载慢等问题,并将iframe作为页面容器存在,在实现硬隔离的同时做到了子应用瞬间切换,解决了微前端框架一直以来的通病,从而实现单应用级别的操作体验。

5.1全屏iframe、共同组件

解决问题:UI 不同步

全屏iframe是指整个浏览器窗口全部给子应用iframe,子应用接管浏览器所有功能,无论是全局拖动、全部蒙层、resizie等,由此UI不同步的问题便不存在了。

但不同应用有个相同的公用部分,因此需要把公共部分做成统一组件,发到npm包中,在每一个应用中引入就行。

5.2 父子应用异步加载

解决问题:加载慢

在前端静态页面中预留子应用dom节点,如下图 所示,每一个div有唯一id,代表一个预制子应用。同时该id对应子应用路由pathname,如New对应/New/*路由,即以New开头的路由全部对应id为"New"的子应用。

当用户进入页面后,父框架拿到浏览器url,并获取到pathname,从而知道需要首先加载那个子应用。并且直接创建iframe,并直接挂到对应的dom节点中,父应用和子应用异步加载。

加载完首个子应用后,开始加载其他子应用,并使用display: none将它们隐藏到页面dom结构中。最终dom节点如下图所示。

5.3 子应用iframe瞬间切换

解决问题:子应用切换卡顿

用户进行多个子应用切换时,擎天框架监听浏览器url地址,如pathname从/New/*变成/Web/*,则将/New/*对应的子应用iframe隐藏起来,将/Web/对应的子应用iframe显示出来,实现应用的瞬间切换。

用户可视范围内只能看一个应用,切换时仅仅是将New应用隐藏不可见,Web应用页面可见。

5.4 路由引擎,同步切换

解决方案:URL不同步

受vue2中数组方法(如push、shift)响应式处理的启发,擎天对前端路由框架进行特殊处理,重写了vue-router的push、replace等方法,当监听到子应用使用以上方法进行路由切换时,会同步到父框架进行操作。

父子应用简单配置后,父子路由同步便做好了。路由切换分为单应用以及多应用间路由切换。

(1)单应用路由切换

单应用子iframe路由切换,如/New/b 切换到/New/c,其pathname结构一致,是单应用的路由切换。子应用先切换路由,随后发送syncRoute给父框架,父框架使用replace方法改变浏览器地址栏即可,具体流程如下图所示。

(2)多应用间路由切换

如/New/b 切换到/Web/c,其pathname结构不一致。子应用先切换路由,随后发送syncRoute消息给父框架,父框架使用replace方法改变浏览器地址栏,同时将应用A隐藏起来,并发送消息到子应用B中。子应用B获得消息后修改其本身路由。

5.5 数据共享

解决问题:内存变量不共享

父应用将需要共享的数据放到store中,并使用syncStore进行注册。

子应用通过类vuex似的 mapGlobalState 方法可以获取父应用store中数据,同时该数据为响应式,数据变更可触发UI重新渲染。

通过mapGlobalMutations获取修改数据的方法,通过该方法可以修改父应用store数据,修改成功后擎天共享数据引擎将修改好的数据分发给各个子应用,保证共享数据一致。

其内部逻辑是:

父应用将需要共享的数据放到store中,并暴露getTopStore(获取store数据)、syncTopMutation(更新store数据)、syncTopStore(分发store数据)等接口。

系统加载时子应用通过getTopStore方法可以获取store中数据,并赋值到子应用$pstore中,从而获得数据响应式等能力。

当某个子应用需要修改共享数据时,调用syncTopMutation方法进行修改,修改成功后擎天通过syncTopStore分发给各个子应用,保证共享数据一致。

六、总结

擎天基于全屏Iframe与搭建公共组件等方式,解决了iframe UI不同步的难题,并充分发挥了iframe作为页面容器的优势,实现了父子应用异步加载、子应用瞬间切换的能力,从而达到单应用项目的体验。

相关文章
|
1月前
|
前端开发 JavaScript 开发者
颠覆传统:React框架如何引领前端开发的革命性变革
【10月更文挑战第32天】本文以问答形式探讨了React框架的特性和应用。React是一款由Facebook推出的JavaScript库,以其虚拟DOM机制和组件化设计,成为构建高性能单页面应用的理想选择。文章介绍了如何开始一个React项目、组件化思想的体现、性能优化方法、表单处理及路由实现等内容,帮助开发者更好地理解和使用React。
77 9
|
2月前
|
人工智能 前端开发 JavaScript
前端架构思考 :专注于多框架的并存可能并不是唯一的方向 — 探讨大模型时代前端的分层式微前端架构
随着前端技术的发展,微前端架构成为应对复杂大型应用的流行方案,允许多个团队使用不同技术栈并将其模块化集成。然而,这种设计在高交互性需求的应用中存在局限,如音视频处理、AI集成等。本文探讨了传统微前端架构的不足,并提出了一种新的分层式微前端架构,通过展示层与业务层的分离及基于功能的横向拆分,以更好地适应现代前端需求。
|
2月前
|
JavaScript 前端开发 API
Vue.js:现代前端开发的强大框架
【10月更文挑战第11天】Vue.js:现代前端开发的强大框架
83 41
|
1月前
|
前端开发 JavaScript API
前端界的秘密武器:掌握这些框架,让你轻松秒杀99%的同行!
前端开发日新月异,掌握几个明星框架如React、Vue.js和Angular,不仅能让工作更得心应手,还能轻松超越同行。React以高效的虚拟DOM和组件化著称;Vue.js简洁易懂,灵活性高;Angular提供全面的解决方案,适合大型应用。此外,轻量级的Svelte也值得关注,其编译时处理设计提升了应用性能。掌握这些框架,结合深刻理解和灵活运用,助你在前端领域脱颖而出。
31 9
|
2月前
|
JavaScript 前端开发 测试技术
前端全栈之路Deno篇(五):如何快速创建 WebSocket 服务端应用 + 客户端应用 - 可能是2025最佳的Websocket全栈实时应用框架
本文介绍了如何使用Deno 2.0快速构建WebSocket全栈应用,包括服务端和客户端的创建。通过一个简单的代码示例,展示了Deno在WebSocket实现中的便捷与强大,无需额外依赖,即可轻松搭建具备基本功能的WebSocket应用。Deno 2.0被认为是最佳的WebSocket全栈应用JS运行时,适合全栈开发者学习和使用。
135 7
|
2月前
|
缓存 前端开发 JavaScript
前端serverless探索之组件单独部署时,利用rxjs实现业务状态与vue-react-angular等框架的响应式状态映射
本文深入探讨了如何将RxJS与Vue、React、Angular三大前端框架进行集成,通过抽象出辅助方法`useRx`和`pushPipe`,实现跨框架的状态管理。具体介绍了各框架的响应式机制,展示了如何将RxJS的Observable对象转化为框架的响应式数据,并通过示例代码演示了使用方法。此外,还讨论了全局状态源与WebComponent的部署优化,以及一些实践中的改进点。这些方法不仅简化了异步编程,还提升了代码的可读性和可维护性。
|
2月前
|
前端开发 JavaScript 中间件
前端全栈之路Deno篇(四):Deno2.0如何快速创建http一个 restfulapi/静态文件托管应用及oak框架介绍
Deno 是由 Node.js 创始人 Ryan Dahl 开发的新一代 JavaScript 和 TypeScript 运行时,旨在解决 Node.js 的设计缺陷,具备更强的安全性和内置的 TypeScript 支持。本文介绍了如何使用 Deno 内置的 `Deno.serve` 快速创建 HTTP 服务,并详细讲解了 Oak 框架的安装和使用方法,包括中间件、路由和静态文件服务等功能。Deno 和 Oak 的结合使得创建 RESTful API 变得高效且简便,非常适合快速开发和部署现代 Web 应用程序。
118 2
|
2月前
|
前端开发 JavaScript 开发者
qiankun(乾坤)微前端框架简介
qiankun(乾坤)微前端框架简介
228 1
|
2月前
|
前端开发 JavaScript 开发者
探索现代Web前端技术:React框架入门
【10月更文挑战第9天】 探索现代Web前端技术:React框架入门
|
2月前
|
存储 前端开发 JavaScript
前端技术深度探索:从基础到现代框架的实践之旅
前端技术深度探索:从基础到现代框架的实践之旅
48 3