微前端思考
February 19, 2017
引言:为什么需要微前端?
在前端工程化快速发展的今天,单体前端应用面临着越来越多的挑战:
- 团队协作问题:多个团队在同一个代码库中开发,代码冲突频繁
- 技术栈限制:整个应用必须使用相同的框架和技术栈
- 部署耦合:一个模块的变更需要整个应用重新部署
- 维护复杂度:应用规模增长带来的复杂度呈指数增长
这些问题的本质是什么?集成、依赖、发布 三个维度的复杂度急剧上升。
微前端作为一种新的架构模式,试图解决这些问题。
什么是微前端?
微前端是一种类似于微服务的架构,它将微服务的理念应用于浏览器端,即将 Web 应用由单一的单体应用转变为多个小型前端应用聚合为一的应用。各个前端应用可以独立运行、独立开发、独立部署。
核心理念
微前端和微服务在设计思想上高度一致,都体现了几个关键原则:
- 单一职责原则:每个服务/应用只负责特定的业务领域
- 迪米特原则:服务间通过明确接口交互,内部实现对外透明
- 独立自治:每个单元可以独立开发、部署、运行
从单体应用到微服务,设计关注点从分层转向了服务拆分;类似地,从单体前端到微前端,关注点从组件复用转向了应用拆分。
微服务 vs 微前端:架构对比
为了更好地理解微前端,我们来对比一下微服务和微前端的架构特点:
维度 | 微服务 | 微前端 |
---|---|---|
独立自治 | 服务是最小单元,语言无关,框架无关(Spring MVC, Flask, Koa.js) 各服务间除调用关系外互相不产生副作用 |
应用是最小单元,框架无关(React, Vue, Angular) 应用间不互相影响(样式、事件、状态) 需要通过 iframe、Web Components 或自定义规范隔离 |
服务治理 | • 服务注册与发现 • 配置中心 • 依赖关系管理 • 链路跟踪、限流、降级、熔断 • 日志与监控 • 生命周期管理 |
• 应用注册与发现 • 运行时配置管理 • 应用依赖关系管理 • 运行环境管理(iframe, Web Worker, 当前窗口) • 宿主环境管理(iframe, Shadow DOM, 当前窗口) • 应用生命周期管理 |
通信机制 | • RPC、HTTP 直接通讯 • 消息中间件(Kafka)异步通讯 • 负载均衡 |
• EventBus/RxJS/Tapable 事件通讯 • 直接获取实例 • PostMessage 跨域通讯 |
聚合方式 | • API 网关聚合 • 业务服务聚合(提单聚合履约、促销、订单等) |
• 主应用聚合 • 由主应用管理子应用生命周期 • 通常用于 B 端后台系统 |
核心应用场景:B 端后台的”超级平台”
微前端最主要的应用场景是 B 端后台系统,这类业务有一个典型特征:入口聚合,超级平台。
痛点分析
B 端业务面临的核心矛盾是:快速增长的需求量 vs 研发复杂度的急剧上升
从需求角度看:
- n 个需求分配给 n 个人,效率提升往往达不到 n 倍
- 很多需求无法拆分,必须由一个人完成
- 加人有时反而会降低效率(2 人做可能需要 4 人日)
- 代码合并、冲突解决占用大量时间
从工程角度看:
- 希望代码拆分足够细粒度,方便测试和减少冲突
- 同时希望保持使用的便利性
- 但这两个目标往往相互冲突
复杂度守恒定律
这里引入一个我在 2015 年想出来的概念:复杂度守恒
复杂度守恒和能量守恒定律类似,指在一个封闭系统中,复杂度不能凭空产生或消失,只能从一个地方转移到另一个地方,在转移过程中复杂度的总量几乎保持不变。
举例说明:
- 生成二维码让后端做,前端复杂度低(调接口获取图片)
- 前端自己生成,后端复杂度低(前端通过 canvas 画图导出)
- 总体复杂度基本相同,只是分布不同
前端复杂度的转移历程
当前前端开发感觉不太复杂,本质是因为我们将大量复杂度转移到了以 webpack 为核心的构建工具中。
但 webpack 与微服务理念存在根本偏差:
- webpack 的假设:面向单一应用,通过构建时静态分析生成依赖关系
- 微前端的需求:运行时动态加载应用,管理应用生命周期
技术演进:从静态构建到动态加载
当前模式的局限
Webpack 的工作模式:
- 静态分析依赖关系
- 构建时生成资源表
- 按路由进行 code-split
- 使用 npm 管理包依赖
这种模式本质上是静态的,而微前端需要的是动态的运行时管理。
未来趋势
以 JavaScript Dynamic Import + HTTP/2 为代表的新规范更适合微前端:
- 不再需要传统的打包工具
- 只需要 loader 工具(如 SystemJS)
- 真正实现运行时动态加载
渐进式过渡方案
为了支持系统渐进过渡和旧版本浏览器,我们需要建设一套动态微前端治理架构。
微前端复杂度转移架构
复杂度在微前端架构中的转移路径:
一堆微前端 → 微前端治理平台 → 线上模板渲染 → 浏览器
治理平台职责
微前端治理平台承担了主要的复杂度:
- 微前端注册:应用注册与发现机制
- 依赖管理:处理应用间的依赖关系
- 应用编排:定义应用加载顺序和规则
- 应用聚合:将多个微前端组合成完整应用
总结与展望
微前端的价值
- 开发效率提升:团队可以独立开发、部署
- 技术栈灵活性:不同应用可以使用不同框架
- 风险隔离:单个应用的问题不会影响整体
- 渐进式重构:可以逐步替换老旧模块
需要解决的挑战
- 运行时性能:动态加载带来的性能开销
- 状态管理:跨应用状态共享和同步
- 用户体验:保证应用间切换的流畅性
- 治理复杂度:构建完善的微前端基础设施
未来方向
微前端架构正在朝着更加标准化和平台化的方向发展:
- Web Components 标准的完善
- 后续应该会有相关的微前端框架逐步推出出来可以持续观望
- 微前端治理平台的标准化
在复杂度守恒的前提下,关键是找到最合适的复杂度分布点,让系统既能满足业务需求,又能保持良好的可维护性。
Written by xi ming You should follow him on Github