当前位置: 首页 > news >正文

【方案】网页由微应用拼图,微前端

大家好,欢迎来到停止重构的频道。

本期我们讨论:微前端

网站的前端网页是否可以像后端应用服务一样,可以拆分为独立开发的子应用,从而提升大型前端项目的协作效率与维护性呢。

我们按这样的顺序展开讨论

  1. 微前端及其好处
  2. iframe与单页应用的弊端
  3. 我们的解决方案
  4. 具体实现

微前端及其好处

微前端指的是一个大型前端应用拆分成多个小型前端应用,小型前端应用可独立开发、独立测试和独立部署。

以我们的官网为例,头部header和底部footer都是固定的,只有中间的部分是变化的。

我们对应的微前端解决方案为:打开的网页是一个基座网页,基座网页上有三个插槽,分别放入“头部Header”和“尾部Footer”。

当网页URL产生变化时,不会发生真正的网页跳转,而是由基座响应这个变化,只替换中间内容部分。

虽然这么说不太不准确,但是也可以这么理解

微前端,就是希望一个网页可以引入别的独立网页

被引入的独立网页可以独立开发、独立部署。

这么一说很多人会想到iframe,iframe确实是其中一个不太好的解决方案,后面会展开讨论。

这里需要补充说明的是,微前端与React/Vue等框架的组件概念是不一样的

微前端的网页碎片是夸工程且独立开发的,甚至一些微前端框架允许引入由不同技术栈开发的网页。

微前端的好处不言而喻,就是它能对需求变更、多团队合作等场景非常友好,所有的网页碎片都可以独立开发、独立替换

在网站特别复杂的时候,这种优势尤为明显,网站可划分更多的插槽,灵活嵌入更多的网页碎片 网页碎片中也可以挖多个插槽,嵌套插入网页碎片。

比如说,网站需要新增一个排行榜的小栏目,这个小栏目需要在多个网页中显示。

那么,微前端就可以单独开发一个排行榜网页,然后多个网页直接引入这个排行榜网页,并对其大小进行限制就可以了。

对于我们而言,我们希望一个大型网站是由多个子系统拼接而成的

其中,一个子系统的前端网页往往是一些碎片零件

比如博客系统的文章编写、文章展示这些网页零件,都不可能直接作为单独网页展示,而是需要嵌入到别的网页中作为其中一部分。

微前端的概念正好能解决这个问题。

也就是说,对于前端部分,我们可以直接接入已经开发好的子系统

而不是每次都从零开始,对着每次都大同小异的UI设计图,写着重复的代码。

这样对持续升级也是十分友好,不需要每次升级都对已有代码进行大范围修改。

iframe与单页应用的弊端

一听到,微前端就是,允许一个网页引入另一个网页

相信大家都会想到iframe,iframe允许在一个网页引入另一个网页,使用方便的同时隔离性也非常好。

虽然,网上有很多人说iframe性能差,基本的证据都是大同小异的。

就是网页是单线程,iframe与宿主网页共用线程会导致性能差。另外,就是iframe可能会加载重复的文件,导致性能浪费等等。

但是,iframe方案我坚持了很多个项目,它在使用上非常简单,不需要过多的学习成本。

另外,性能问题也是几乎是不存在的,毕竟用户并不是在用单片机上打开网页,iframe方案甚至比很多花里胡哨框架的响应速度还要高。

让我放弃iframe的理由是,iframe存在样式割裂的问题

比如弹出模块框,黑色背景不能全屏网站显示,若是想固定某个html元素,只能通过Js代码计算固定,而Js代码计算固定,会有抖动等不可解决的问题

对于微前端另一个比较常见的方案是单页应用

通过一个网页js入口,可以将网页碎片封装成各种组件,按需加载这些组件。

但是,这样是单个工程的解决方案,不能夸工程引入。

除非网站内容非常少,不然单论一个工程而言,团队合作中的代码冲突、目录混乱 都会让人头皮发麻。

当然,除了传统的单页应用工程,还有服务端渲染的框架,是可以允许夸工程引入的

但是,这些解决方案都有一个致命问题

就是在切换网页碎片时,浏览器虽然可以清理掉不再需要的HTML/CSS部分,但是却没办法清理不再需要的JS代码,也就是内存占用会越来越高

所以单页应用在大型网站的表现并不佳,把整个大型网站的前端做成一个单页应用也是不可行的,尝试过的团队,都是一做一个不吱声。

我们的解决方案

iframe和单页应用的弊端其实也凸显出了,微前端的两个核心问题

1、网页样式部分不希望有割裂感

2、JS部分需要可以清理

针对以上的核心问题,我们借鉴了wujie框架的设计思想。

将一个网页分成了两个部分:UI部分和Js部分。

UI部分放在宿主网页的ShadowDom中隔离,Js部分放在iframe沙箱中运行。

其中,ShadowDom是dom树下的隔离节点,与dom树在同一个文档流的同时,样式可以进行隔离。

这样就可以解决,纯Iframe方案,UI样式割裂的问题,也能解决,单页应用方案,JS代码累积的问题

Trick2也因此扩展了微前端相关功能,在开发调试网页时,按正常网页开发调试即可,当工程需要发布时,从原来的普通打包方式改为SPA方式即可

网页需要引入SPA方式打包的网页碎片时,需要采用_BoxPage组件引入

引入的方式也很简单,像iframe一样,就是设置目标网页的URL即可

具体实现

接下来是具体的实现方式,由于需要将网页分离为UI部分和Js部分UI部分放在ShadowDom中隔离,Js部分放在iframe沙箱中运行。

所以具体实现也分成了4个步骤,具体的代码实现可以翻看_BoxPage组件的源码。

  1. 分离网页的UI部分和JS部分
  2. 将UI部分插入宿主网页的ShadowDom中
  3. 将JS部分放入iframe沙箱中运行
  4. 重新关联UI部分和JS部分

首先是分离UI部分和JS部分,这部分其实很简单,就是将目标URL的HTML文本获取下来,再通过现成JS函数转换为HTML对象。

<link>标签和body为UI部分,<script>标签为JS部分。

分离完毕后,直接将UI部分写入当前网页的ShadowDom中,ShadowDom其实就是在HTML节点下开启一个ShadowDom节点,ShadowDom节点的窗体大小受外层节点的影响。

剩下的JS部分通过iframe的srcdoc属性写入即可,也就是iframe中只包含目标网页的JS部分。

值得一提的是,IOS的微信浏览器是不支持上述iframe属性的,需要通过比较老旧的方式写入。

最后一步是关联UI部分和JS部分,更具体的说,是劫持JS代码中的document、window等基础对象,使其指向Shadowdom中的UI部分。

这需要分两部分完成先是宿主网页需要创建proxy对象,用于替代JS代码中的document、window等基础对象。

创建proxy对象的原因,是可以精准控制哪些变量、函数使用宿主网页,哪些指向ShadowDom中的UI部分。

然后,在网页打包时需要将document、window对象改为宿主网页传入的proxy对象。

实际上就是在webpack打包时,将所有js文件的外层都套一层自动执行函数,就可以将document、window对象劫持为上面的proxy对象。

至于为什么我们源码中除了document、window对象以外,还劫持了其他对象

这些都是在调试时发现的,这些特殊对象的使用都存在于某些第三方库中,若不一并劫持,网页将运行不成功。

以上就是大概的实现步骤,具体可以翻看_BoxPage组件的代码,很多琐碎的细节没办法在这里展开。

总结

以上是我们的微前端解决方案。

我们希望微前端网页的引入方式跟iframe是一样的,只需要目标网页的URL。

微前端网页开发上也不希望有特殊适配,只需要更换打包方式即可。

我们的微前端方案,确实只是一个网页可以引入另一个独立网页。

与其他比较重的微前端解决方案不同,它们都包含更加复杂的网页跳转/切换方式,也就是网页路由。

关于网页路由,我们会在后续的网站基座解决方案提及,因为网页路由我们保持了最原始直接的a标签跳转。我们不希望徒增不必要的学习成本和多余的适配工作。

http://www.dtcms.com/a/292620.html

相关文章:

  • 『 C++ 入门到放弃 』- 红黑树
  • 一文详解Java类中的构造器是什么及主要特性
  • 70.爬楼梯
  • ABP VNext 报表:EPPlus DinkToPdf 多格式导出
  • redis秒杀之lua脚本
  • 20250722解决在Ubuntu 24.04.2下编译RD-RK3588开发板的Android13出现找不到python2的问题
  • GraphRAG的部署和生成检索过程体验
  • C++11--锁分析
  • npm全局安装后,依然不是内部或外部命令,也不是可运行的程序或批处理文件
  • 大数据量查询计算引发数据库CPU告警问题复盘
  • 使用ZYNQ芯片和LVGL框架实现用户高刷新UI设计系列教程(第二十二讲)
  • Linux_Ext系列文件系统基本认识(一)
  • Product Hunt 每日热榜 | 2025-07-22
  • “鱼书”深度学习入门 笔记(1)前四章内容
  • day19 链表
  • 【科研绘图系列】R语言绘制柱状堆积图
  • 基于 Vue,SPringBoot开发的新能源充电桩的系统
  • 豪鹏科技锚定 “AI + 固态” 赛道:从电池制造商到核心能源方案引领者的战略跃迁
  • mybatis拦截器实现唯一索引的动态配置
  • 网络基础DAY16-MSTP-VRRP
  • git reset --soft和 git reset --mixed的主要区别
  • 智能制造——解读制造业企业数字化转型实施指南2025【附全文阅读】
  • libgmp库(GNU高精度算术库)介绍
  • 算法训练营day28 贪心算法②122.买卖股票的最佳时机II、55. 跳跃游戏、 45.跳跃游戏II 、1005.K次取反后最大化的数组和
  • Web服务器(Tomcat、项目部署)
  • 0722 数据结构顺序表
  • 循环神经网络--NLP基础
  • <另一种思维:语言模型如何展现人类的时间认知>总结
  • 大型语言模型(Large Language Models,LLM)
  • Science Robotics 机器人成功自主完成猪胆囊切除手术