微前端:前端的微服务

2025-06-10

微前端:前端的微服务

微服务是构建小型、自主、可独立工作的团队的流行方式。然而,微服务本质上只能在后端工作。即使采用最佳的微服务架构,前端开发仍然需要高度的相互依赖,这会带来耦合和通信开销,从而降低每个人的工作效率。

我们能否将微服务架构模式应用于前端?答案是肯定的。Netflix ZalandoCapital One等公司已将这种模式推向前台,微前端奠定了基础。本文将探讨微前端、其优缺点以及它与传统微服务的区别。

前端微服务

微前端就是将微服务方法引入前端。换句话说,微前端由不同团队拥有的组件组成,这些组件可以独立部署。这些组件的组合旨在打造一致的用户体验。

从左到右,我们展示了四种场景。所有场景中,中间的一条水平线将前端和后端一分为二。左侧是一个横跨前后端(包括 UI)的单体应用。其次,后端是一个单体应用,前端是一个 SPA 网页(UI 与后端分离)。第三种场景,前端是同样的 SPA,但单体应用在后端被拆分成微服务。最后一种场景在后端使用微服务,在前端使用微前端。前端由不同的组件或小部件组成,彼此独立。

单体应用可以通过多种方式进行分解。我们可以拆分前后端,或者在后端使用微服务。我们甚至可以将前端重新创建为由不同团队管理的独立组件集合。

使用微前端,没有哪个团队能够完全掌控 UI。相反,每个团队都拥有一部分屏幕、页面或内容。例如,一个团队可能负责搜索框,而另一个团队可能负责根据用户喜好编写建议。其他团队可能负责音乐播放器、播放列表管理或结算页面的渲染。我们增加了复杂性,但团队也因此获得了更大的自主权。

这是音乐流媒体网站的线框图。一共有 5 个团队:一个负责“首页”本身,一个负责播放列表,一个负责推荐,一个负责搜索框,还有一个负责音乐播放器。每个团队都分配了首页内相应的小部件或组件。

前端功能由不同的团队管理,独立部署,并以对最终用户透明的方式注入主页。

微前端的优势与挑战

微前端具有与微服务类似的优势。也就是说,我们可以通过将前端代码拆分成独立的部分,由不同的团队负责,从而扩展开发规模。与微服务一样,每个功能都可以随时独立发布,几乎无需协调。这可以提高更新频率。

垂直团队

微前端支持创建垂直团队,这意味着全栈开发人员团队可以同时拥有后端和前端的功能。

垂直团队负责处理特定功能或组件的所有特性和代码。我们有三个团队:建议、搜索和播放列表。每个团队独立管理各自的微服务后端和微前端。

全栈垂直团队负责功能或组件的前端和后端。

持续部署组件

微前端的每个部分都是一个可部署单元。这使得团队可以发布自己的更改,而无需等待发布列车或依赖其他团队完成工作。最终结果是前端可以每天更新多次。

每个团队都有独立的源码仓库、CI/CD 流水线和生产服务,用于服务微前端内容。所有独立的微前端组合起来,在客户端上渲染出一个统一的前端。

每个团队可以拥有独立的代码库、CI/CD 流水线和服务机器。或者,我们可以将所有内容托管在一个单一代码库上,并共享一个 CI/CD 流水线。

微前端设计的挑战

微前端的主要挑战是创建快速且响应迅速的客户端。我们绝不能忽视前端所处的内存、CPU 和网络环境有限这一事实,否则最终会导致 UI 运行缓慢。

流畅的用户界面对于产品的成功至关重要。最近的一项调查指出,“加载时间为 1 秒的网站的转化率比加载时间为 5 秒的网站高出 3 倍”。用户每等待一秒,就意味着金钱的流失。

除了微服务面临的所有挑战之外,微前端设计还带来了一些问题:

  • 隔离性:每个团队的代码最终必须共存于同一个浏览器。我们必须谨慎地隔离各个模块,以避免代码或代码风格冲突。
  • 共享资源:为了避免重复并保持前端精简,组件应尽可能共享资产和库,这可能会产生不良的耦合。
  • 可访问性:过度依赖 JavaScript 来呈现页面会对可访问性产生负面影响。
  • 样式:当 UI 由多个团队开发的组件组成时,保持一致的外观会变得更加复杂。细微的风格差异都会让人感到不协调。

协调:由于存在如此多的移动部件,API 需要定义明确且稳定。团队必须协调微前端中不同组件之间以及与后端微服务之间的通信方式。

构建微前端的原则

有两种互补的方法可以从单独的微前端组件渲染统一的 UI:服务器端渲染和客户端渲染。

服务器端渲染(SSR)

服务器端渲染提供更快的性能和更易于访问的内容。服务器渲染是快速提供内容的良好替代方案,尤其是在低端手机等低功耗设备上。当 JavaScript 被禁用时,它也是一个合适的回退模式。

服务器端渲染示意图。各种微服务由 Web 服务器轮询。它们返回 HTML 片段,Web 服务器会组装这些片段并转发给用户的浏览器。

Web 服务器将不同微服务提供的内容组合成完整的页面。这将作为第一个内容页面。之后,可以使用 Hydration 添加更多动态内容。

我们有几种执行 SSR 的方法:

例如,我们可以使用 SSI 从 HTML 渲染页面,如下所示:

<div>
  <!--#include virtual="/hello-world" -->
</div>
Enter fullscreen mode Exit fullscreen mode

virtual关键字使 Web 服务器从 URL 或 CGI 程序请求内容。在我们的例子中,我们需要设置 Web 服务器,使其根据路径/hello-world使用合适的片段来响应请求:

<h1>Hello World!</h1>
Enter fullscreen mode Exit fullscreen mode

许多 Web 框架都使用 SSR 来渲染首屏。此外,还有一些有趣的 SSR 专用实用程序,例如compoxurenodesitail

客户端渲染(CSR)

客户端渲染通过从微服务获取数据并操作 DOM 来在用户浏览器中构建页面。大多数 Web 框架都使用某种形式的 CSR 来提升用户体验。

客户端渲染示意图。用户浏览器从 CDN 下载页面源代码。加载时,页面会从不同的微服务端点加载数据并动态渲染视图。

CSR 使用端点提供的数据在用户浏览器上动态呈现页面。

我们编写松耦合组件的主要工具是自定义元素。自定义元素是 HTML 标准的一部分。它们允许我们创建新的 HTML 标签,并为其附加逻辑和行为。

自定义元素使用 JavaScript 在页面上动态安装和卸载:

// hello-world-component.js

class HelloWorld extends HTMLElement {
  connectedCallback() {
    this.innerHTML = `<h1>Hello world</h1>`;
  }
}

customElements.define('hello-world', HelloWorld);
Enter fullscreen mode Exit fullscreen mode

一旦定义,我们就可以像任何其他 HTML 标签一样使用新元素:

<hello-world></hello-world>
Enter fullscreen mode Exit fullscreen mode

在示例中,整个页面将包含一个脚本标签来获取 JavaScript 组件:

<!doctype html>
  <head>
    <meta charset="utf-8">
    <title>Microservice Example</title>
  </head>
<body>
 <script src="./hello-world-component.js" async></script>
 <hello-world></hello-world>
</body>
Enter fullscreen mode Exit fullscreen mode

虽然大多数前端框架都可以用于微前端,但有些框架是专门为微前端设计的:

  • Piral :实现了称为Pilets 的独立组件。Pilets 是捆绑内容和行为的模块。
  • Ragu:一个框架中的框架。它允许我们将任何框架中编写的代码嵌入到小部件中。
  • 单一 SPA:一个元框架,使用 React、Angular、Ember 等任意前端框架组合来拼凑 UI。
  • Frint:另一个用于构建基于组件的应用程序的模块化框架。与 React、Vue 和 Preact 集成。
  • Module Federation:一个 WebPack 插件,用于通过打包单独的构建来创建单页应用程序 (SPA)。这些构建可以独立开发。

结论

切换到微前端架构可以赋予我们的开发团队更多自主权,从而加速开发。然而,适用于微服务的注意事项也同样适用于微前端。我们需要一个经过验证的设计,这意味着微前端并不适合新建项目。

新项目最好采用传统模式,例如由单个团队管理的单页应用程序 (SPA)。只有当前端经受住了时间的考验,我们才能将微前端视为未来的发展方向。

鏂囩珷鏉ユ簮锛�https://dev.to/semaphore/microfrontends-microservices-for-the-frontend-4la4
PREV
Kotlin Hipster = Spring Boot + Kotlin
NEXT
如何让页脚固定在页面底部