前言
HTML 内联框架元素 (<iframe>
) 表示嵌套的browsing context。它能够将另一个 HTML 页面嵌入到当前页面中。
每个嵌入的浏览上下文(embedded browsing context)都有自己的会话历史记录 (session history)和DOM 树。包含嵌入内容的浏览上下文称为父级浏览上下文。顶级浏览上下文(没有父级)通常是由 Window 对象表示的浏览器窗口。
页面上的每个<iframe>
都需要增加内存和其他计算资源,这是因为每个浏览上下文都拥有完整的文档环境。虽然理论上来说你能够在代码中写出来无限多的<iframe>
,但是你最好还是先看看这么做会不会导致某些性能问题。
在复用和组件化的潮流中 HTML 也不是那么的格格不入,毕竟时下最流行的 Vue,React,Ng 都是实现自定义 HTML 组件强有力框架。然而框架各自为阵,语法和使用方式不同,学习成本不同。
Web Components 是 W3C 推动的一项标准,旨在丰富 HTML 的 DOM 特性,让 HTML 有更强大的复用能力。目前它包含三项主要技术,它们可以一起使用来创建封装功能的定制元素,可以在你喜欢的任何地方重用,不必担心代码冲突。
这三项技术分别为:
- Custom elements(自定义元素): 一组 JavaScript API,允许您定义 custom elements 及其行为,然后可以在您的用户界面中按照需要使用它们。
- Shadow DOM(影子 DOM):一组 JavaScript API,用于将封装的“影子” DOM 树附加到元素(与主文档 DOM 分开呈现)并控制其关联的功能。通过这种方式,您可以保持元素的功能私有,这样它们就可以被脚本化和样式化,而不用担心与文档的其他部分发生冲突。
- HTML templates(HTML 模板):
<template>
和<slot>
元素使您可以编写不在呈现页面中显示的标记模板。然后它们可以作为自定义元素结构的基础被多次重用。
微前端是什么?
在过去的15年里,我作为一名软件开发人员参与了许多项目。在这段时间里,我有多次机会观察到一种在整个行业重复出现的模式:与少数人合作一个新项目感觉好极了。每个开发人员都对所有功能有一个概述。功能构建迅速。与同事讨论话题很简单。当项目范围和团队规模增加时,这种情况会发生变化。突然间,一个开发人员无法再了解系统的每一个边缘。团队内部会出现知识孤岛。复杂性上升——对系统的一部分进行更改可能会对其他部分产生意想不到的影响。团队内部的讨论更加繁琐。之前,团队成员在咖啡机上做决定。现在,你需要召开正式会议,让每个人都站在同一立场上。弗雷德里克·布鲁克斯在1975年出版的《神话人月》一书中描述了这一点。在某些情况下,向团队中添加新的开发人员并不能提高生产力。
为了减轻这种影响,项目通常被分为多个部分。通过技术划分软件,从而划分团队结构,成为一种时尚。我们引入了一个前端团队和一个或多个后端团队的水平层。Micro前端描述了一种替代方法。它将应用程序划分为垂直切片。每个切片都是从数据库到用户界面构建的,并由一个专门的团队运行。不同的团队前端集成在客户的浏览器中,形成最终页面。这种方法与微服务架构有关。但主要区别在于,服务还包括其用户界面。这种服务的扩展消除了对中央前端团队的需求。以下是公司采用微前端架构的三个主要原因:
1、优化功能开发--一个团队包括开发功能所需的所有技能。不需要单独的前端和后端团队之间进行协调。
2、让前端升级更容易——每个团队都拥有从前端到数据库的完整堆栈。团队可以决定独立更新或切换其前端技术。
3、提高对客户的关注度--每个团队都将其功能直接交付给客户。不存在纯粹的API团队或运营团队。
在本章中,您将了解微前端解决了哪些问题,以及何时使用它们是有意义的。
微前端是一种多个团队通过独立发布功能的方式来共同构建现代化 web 应用的技术手段及方法策略。
Techniques, strategies and recipes for building a modern web app with multiple teams that can ship features independently. -- Micro Frontends
通俗来说,就是在一个web
应用中可以独立的运行另一个web
应用。
微前端有什么使用场景呢?
举例
-
比如制作一个企业管理平台,把已有的采购系统和财务系统统一接入这个平台;
-
比如有一个巨大的应用,为了降低开发和维护成本,分拆成多个小应用进行开发和部署,然后用一个平台将这些小应用集成起来;
-
又比如一个应用使用
vue
框架开发,其中有一个比较独立的模块,开发者想尝试使用react
框架来开发,等模块单独开发部署完,再把这个模块应用接回去。
一个完善的的微前端框架应该具备哪些能力呢?
能力
-
子应用的加载和卸载能力
页面需要从一个子应用切换到另一个子应用,框架必须具备加载、渲染、切换的能力。
-
子应用独立运行的能力
子应用运行会污染全局的 window 对象,样式会污染其他应用,必须有效的隔离起来。
-
子应用路由状态保持能力
激活子应用后,浏览器刷新、前进、后退子应用的路由都应该可以正常工作。
-
应用间通信的能力
应用间可以方便、快捷的通信。
使用微前端有什么收益呢?(@reference 乾坤)
收益
-
技术栈无关
主框架不限制接入应用的技术栈,微应用具备完全自主权。
-
独立开发、独立部署
微应用仓库独立,前后端可独立开发,部署完成后主框架自动完成同步更新。
-
增量升级
在面对各种复杂场景时,我们通常很难对一个已经存在的系统做全量的技术栈升级或重构,而微前端是一种非常好的实施渐进式重构的手段和策略。
-
独立运行时
每个微应用之间状态隔离,运行时状态不共享。
可能有人会有疑问直接使用iframe
不就可以做到吗?
基于浏览器的软件很快就会变得复杂且难以维护,尤其是当它被实现为大型单页应用程序时。通过采用微前端方法并将web应用程序设计为功能系统,您可以提供更快的功能开发、更容易的升级,并选择您在堆栈中使用的技术。Micro Frontends in Action是您简化笨重前端的指南,它由定义良好的小单元组成。
iframe 方案
采用iframe
的方案确实可以做到,而且优点非常明显。
优点
- 非常简单,使用没有任何心智负担。
web
应用隔离的非常完美,无论是js
、css
、dom
都完全隔离开来。
由于其隔离的太完美导致缺点也非常明显。
缺点
- 路由状态丢失,刷新一下,
iframe
的url
状态就丢失了。 dom
割裂严重,弹窗只能在iframe
内部展示,无法覆盖全局。web
应用之间通信非常困难。- 每次打开白屏时间太长,对于SPA 应用来说无法接受。
single-spa 方案
single-spa是一个目前主流的微前端技术方案,其主要实现思路:
- 预先注册子应用(激活路由、子应用资源、生命周期函数)。
- 监听路由的变化,匹配到了激活的路由则加载子应用资源,顺序调用生命周期函数并最终渲染到容器。
乾坤微前端架构则进一步对single-spa
方案进行完善,主要的完善点:
- 子应用资源由 js 列表修改进为一个
url
,大大减轻注册子应用的复杂度。 - 实现应用隔离,完成
js
隔离方案 (window
工厂) 和css
隔离方案 (类vue
的scoped
)。 - 增加资源预加载能力,预先子应用
html
、js
、css
资源缓存下来,加快子应用的打开速度。
总结一下方案的优缺点:
优点
- 监听路由自动的加载、卸载当前路由对应的子应用。
- 完备的沙箱方案,
js
沙箱做了SnapshotSandbox
、LegacySandbox
、ProxySandbox
三套渐进增强方案,css
沙箱做了两套strictStyleIsolation
、experimentalStyleIsolation
两套适用不同场景的方案。 - 路由保持,浏览器刷新、前进、后退,都可以作用到子应用。
- 应用间通信简单,全局注入。
缺点
- 基于路由匹配,无法同时激活多个子应用,也不支持子应用保活。
- 改造成本较大,从
webpack
、代码、路由等等都要做一系列的适配。 css
沙箱无法绝对的隔离,js
沙箱在某些场景下执行性能下降严重。- 无法支持
vite
等ESM
脚本运行。
无界方案
在乾坤的issue
中一个议题非常有意思,有个开发者提出能否利用iframe
来实现js
沙箱能力,这个idea
启发了无界方案,应用加载机制和 js 沙箱机制。
将子应用的js
注入主应用同域的iframe
中运行,iframe
是一个原生的window
沙箱,内部有完整的history
和location
接口,子应用实例instance
运行在iframe
中,路由也彻底和主应用解耦,可以直接在业务组件里面启动应用。
Quarkd方案
Quarkd(Quark design缩写)是一种全新的组件库,底层基于Web Components,不同于传统组件框架(如Antd, Vant),需要浏览器中需要做大量前置工作。Quarkd则将这些工作放到构建应用程序的编译时来处理。组件的数据更新响应由浏览器自身API处理,更简单,更高效!
qiankun方案
qiankun 是一个基于 single-spa 的微前端实现库,旨在帮助大家能更简单、无痛的构建一个生产可用微前端架构系统。
参见:
<iframe> - HTML(超文本标记语言) | MDN
Web Component - Web API 接口参考 | MDN
webcomponents.org - Discuss & share web components
Web Component Essentials - Video Course and EBook - Cory Rylan
Micro Frontends - extending the microservice idea to frontend development
Micro Frontends in Action
qiankun - qiankun
无界 | 极致的微前端框架
Quarkd(Quark design) - 下一代浏览器原生组件库,它可以同时在任意框架或无框架中使用。