解决拖延症分四步
- 把大目标化整为零
- 清空桌面
- 行动起来
- 及时奖励
大家好,我是柒八九。
今天我们来谈谈一个比较时髦的概念- 微前端。
微前端是一套用于组织大型前端应用的指导规范。是受后端微服务启发而发展而来。
虽然微前端是一个备受关注的趋势性话题,但其中有一些概念是很难准确定位的。当理解一个新的趋势或技术时,首先需要理解它是解决哪些现存的问题。
接下来,我们就从微前端解决了哪些现存前端问题,并在解决这些问题的过程中做出了哪些取舍和权衡。
话不多说,我们开始。
微前端试图解决什么问题?
理解微前端的最简单的方法是把它们看作是对大规模应用如何进行组织的一种技术解决方案。
对于大型应用来说,有许多前端团队想要快速产生,并且这些团队能够在开发流程上互相解耦。这样他们就可以独立工作而不妨碍对方。
这在前端的实践中意味着什么。
- 独立的可构建的前端资源允许团队拥有属于自己的构建流程。这避免了冗长的构建时间,并防止个别团队被其他成员的误操作而影响项目构建。
- 独立的可部署的前端资源允许解耦的这些团队定期将他们的代码独自发布到生产环境,而不需要复杂的部署顺序。
这也意味着当bug出现和事故发生时,代码可以自动回滚,而不会干扰到其他团队的项目开发。 - 清晰的所有权在大型项目上是必要的。在大型项目中,如果某个功能不被维护,那几乎就像它不存在一样。因为没有人负责保持它的更新,它往往会变得难以维护。
这些是微型前端希望解决的一些核心问题。
如果解决得当,它可以加快团队的开发速度。这也是微前端被推崇的一个强有力的原因。
定义微前端
正如 微服务是后端关于如何构建服务的一种指导原则一样,微前端也可以用同样的方式看待。
作为一套由特定技术实现的指导原则。
有一些底层技术,如webpack模块联盟,使微前端成为可能。还有像single-spa
这样的流行框架,为实现微前端做出了不小的努力。
以下是摘自micro-frontends.org的微前端的原则,在此转述。
- 技术不可知
意味着团队可以选择他们想要的任何前端技术栈。但是建议将WebComponent
作为通用的共享组件并对其进行标准化处理。 - 隔离团队代码
是指通过拥有独立构建的、能够单独部署的应用程序,使得团队能够解耦开发。 - 当团队之间共享数据时,可以通过团队前缀来实现
这意味着对自定义事件名称和诸如本地存储和cookie
之类的东西要有一个名称间隔,以避免碰撞。 - 优先使用浏览器功能而不是自定义API。
这通常意味着优先使用自定义元素和WebComponent
以及自定义事件进行微前端项目之间的通信。 - 建立一个有弹性的网站
意味着在建立你的微前端时要考虑到渐进式增强。
其中有些是可以解释的。这可能是设计上的问题,因为微前端并不指向一个特定的通用实现。这也是为什么对微前端的用途会让人感到困惑的原因之一。
与组件岛模式的比较
像Fresh、Astro和Marko这样的Web框架提倡{组件岛模式|Component Islands Pattern}。
微前端在表面上和组件岛模式看起来很相似,都是将一个页面的渲染分割成多个独立的组件渲染。
但其背后的理念却截然不同。
组件岛模式的指导原则是
- 默认使用服务器端渲染而不是客户端渲染
- 只向客户端发送必要的互动内容。
重点是尽量减少Javascript的不必要的开销。
这几乎是对传统的多页面架构的一种回归,在这种架构中,Javascript被镶嵌在服务器渲染的HTML页面上,使其具有一定的交互性。
在新的实现方案中,使用Preact/React/Vue
等现代技术代替jQuery
来编写页面逻辑,并封装成组件。
而,微前端都是为了解决组织问题,而不是性能问题。它被用在由许多团队合作的大型SPA的背景中。
微前端的潜在问题
微前端有着崇高的目标,旨在解决真正的大型项目组织问题。
然而,基于他们上面描述的理念,在实际开发中,还是需要在一些方面额外注意,以免造成不必要的问题。
潜在的性能隐患
在团队成员庞杂和项目应用比较复杂的情况下,让团队自由地选择他们想使用的技术栈,需要有一些重要的权衡。
在后端微服务的背景下。让团队选择他们的技术栈是有意义的。因为终端用户不需要下载和运行这些代码。
但在前端,情况就不同了。你最终会迫使用户下载和运行解决各种常见问题的代码,如样式设计、获取和改变数据、日期格式等。以不同的方式,用不同的工具和框架,重复多次。这是个很大的开销。
我们就不能把所有的东西都用代码分割吗?每个微前端都可以在页面加载时选择性地进行代码拆分。代码拆分并不是银弹。而且,页面往往是瀑布式的组件加载,然后获取数据,导致更多的异步加载,这才是页面加载缓慢的真正原因。尤其是在移动端,对网络延迟的敏感度往往更高。
困难的依赖性管理
即使通过同一个库来解决功能共享的问题,但是,在规模比较大的情况下,总是存在着该库的不同版本需要保持更新的问题。特别是对于像高优先级的更新。
多个重复的横向依赖导致用户多次重新下载同一代码(不同版本)。在有很多团队的情况下, 即使是使用同一个打包工具(webpack
)的情况下,这也是一个棘手的问题,如果每个团队都有自己的打包工具,那后果更是不堪设想。
这里简单说一下,为什么使用同一个打包工具,能够做到优化处理。
在前端工程化之构建工具中我们讲过,对前端资源先后经过了很多阶段,从刚开始的纯手动的资源解析和压缩,到后来基于任务形式的自动化处理。它们的主要目的都是对资源进行转换或者压缩,没法进行在项目级别的优化处理。到后来出现了基于模块化的构建方式,分析模块之间的依赖关系,从入口模块开始构建一棵依赖图,中间遇到的用到的 js、css、图片等都会作为他的依赖。然后对依赖图的每个节点分别用对应的编译器处理。
然后,由于有了各个资源的依赖关系,我们就可以做一些以往无法实现的优化操作。
Tree-Shaking
-有了依赖关系后,可以通过依赖分析,去掉一些没用的代码Code-Splitting
- 这些模块根据功能和类型拆分到不同的分组(chunk)里,然后生成不同的文件,然后将变更频繁和几乎不动的模块划分到不同的chunk
,并封装到特定文件中,针对几乎不会变更的资源和模块,则可以利用浏览器缓存进行资源的优化处理Lazy-Load
:生成的代码,拥有自己的runtime
,这样可以实现模块的lazy load
,也就是把Code-Splitting
分出来的 chunk,在运行时动态加载
而关于webpack
如何实现资源查找和解析的,可以参考工程化之webpack打包过程
服务的粒度划分
类似于后端微服务存在的问题,前端微服务也有类似的困惑。微服务的划分粒度如何判定?
如果我们把事情分解得太多,我们就有可能产生依赖关系,需要我们把多个前端部署在一起。这就违背了,我们使用微服务要解决前端服务可以独立构建和部署的初衷。
回顾总结
微前端都是为了解决组织问题,而不是性能问题
后记
分享是一种态度。
参考资料:
全文完,既然看到这里了,如果觉得不错,随手点个赞和“在看”吧。
分类: