共计 3612 个字符,预计需要花费 10 分钟才能阅读完成。
导读:”微前端”这个词当初对前端同学来说曾经比拟相熟了,各种计划也曾经落地开花,比拟支流如 single-spa、乾坤,起初的也有 webpack 模块联邦。爱番番团队在我的项目初期后端微服务化的过程中,前端也落地了本人的微前端计划,更好的服务于麻利开发,晋升交付效率。
全文 3308 字,预计浏览工夫 10 分钟。
一、背景
爱番番团队后端应用微服务架构,实现麻利开发和部署。为配合微服务架构模式,前端须要对原有的 web 端单体我的项目进行拆分,每个微服务对应局部的前端须要有独立的代码库,可能独立开发、测试、部署、上线,实现团队自治;同时在用户感知层面,各个前端模块是一个整体,一个对立的零碎,有雷同的页面格调和交互格调。
二、初步计划
鉴于以往的我的项目教训,咱们在运行时整合多个前端利用为一个对立的利用时多采纳的是 iframe 的计划,但 iframe 计划有这些问题:
- 切换速度慢,影响用户体验
- 页面外部弹窗不能笼罩整个利用窗口,用户体验差
- 利用之间通信简单
以上这些问题极大升高用户体验,是咱们不能采纳的。咱们心愿拆分了代码库之后也能保障如下这些体验:
- 在用户感知上,零碎和之前的单体利用一样晦涩
- 放弃之前的交互格调
- 开发人员开发时,也能像之前开发单页利用一样不便
从单页利用的按路由拆分代码形式产生的另一个计划:
在做单页利用的性能优化时,个别都会应用按路由拆分代码的形式。用户拜访一个单页利用时,并不加载全部内容,只加载必要的前置依赖,而后跟进以后页面路由异步加载路由对应 js 和 css,异步渲染页面,晋升拜访性能。
沿着这个思路,联合 iframe 计划中对立入口的形式,咱们的思路是,拆分的独立利用是页面路由对应 js 和 css 的一个汇合,再有一个对立入口的利用保留所有菜单,用户点击菜单时,异步加载对应的利用中的页面路由代码,渲染对应页面。
三、须要解决的问题
3.1 路由解析
主工程负责存储和渲染所有菜单,负责作为一个页面渲染的容器,同时负责前端路由的解析。主工程须要通过路由解析找出对应的子工程和对应的子工程的页面,失去页面资源地址,加载页面资源,渲染页面。
上述性能正是一个前端路由要做的事件,咱们间接应用技术栈中已有的前端路由插件,并进行革新。
路由规定:
例如:拜访 /s1/aa=> 加载 https://xx.cdn.com/s1/s1\_aa.js 组件。
在 vue-router 的守卫函数中判断组件未加载的状况下,解析路由加载对应页面的 vue 组件,加载完的组件间接交给 vue-router,由 vue-router 主动解决渲染过程。
3.2 配合路由解析标准子工程打包产出
路由解析逻辑实现后,咱们须要对子工程的编译产出进行解决,解决成按路由拆分成的前端资源(js 和 css)。这个拆分只须要把每个路由作为 webpack 编译的一个入口,主动就会打包出每个入口对应的一个 js 和 css。
个别的形式是在 webpack 配置文件中,应用脚本读取我的项目中路由文件,整合所有入口,配置到 webpack 的配置中。
咱们把这个过程对立封装在命令行工具中,在编译过程中,对立读取我的项目的固定路由配置文件,解析出所有入口。
在这个根底上,以往一个单页利用按路由拆分代码时,都会把公共的文件进行提取,个别的形式是 common.js 整合所有业务公共文件,vender.js 整合所有第三方库或框架。咱们这解决微前端的子工程中也沿用这个拆分代码的优化形式。
这样优化了拆分代码的形式后,咱们在加载路由对应的资源时,须要前置加载 common.js 和 vender.js。
3.3 解决子工程开发时独立运行问题
因为只有主工程是一个残缺的我的项目,蕴含单页利用的入口 html,前端路由,页面容器,它能够在本地实现独立的运行,只是没有页面。子工程因为只是一个页面资源的汇合,不是一个残缺利用,独自运行不起来。
咱们别离解决主工程和子工程本地运行问题。
子工程:咱们采纳把主工程作为 npm 依赖包的形式引入子工程,通过在编译入口中退出主工程入口,使主工程和子工程中路由入口同时都能编译;把 npm 依赖包中主工程中的 html 作为我的项目入口 html,主工程入口 js 文件作为我的项目入口 js 文件,而后就进入了路由解析逻辑。如果是以后子工程本身路由,cdn 资源前缀就是本地,其余路由应用测试环境 cdn。
主工程:在本地开发时,本人作为入口启动本地服务,其余子工程的门路能够应用测试环境资源。
3.4 解决版本变动导致资源地址变动问题
因为咱们解析路由异步加载路由资源渲染的形式齐全依赖资源的地址,当咱们的子工程发版导致版本变动时,咱们须要晓得对应的资源的新地址。
咱们应用了一种比较简单形式实现版本的治理——应用工夫戳管制我的项目版本,应用工夫戳的益处有:
1. 版本保护简略高效,咱们不须要保护更多的信息,比方每个文件的 hash。
2. 因为对立了 hash,咱们能够只应用一个全局文件维护所有我的项目版本,比每个我的项目一个独自的版本文件,在运行时加载和解析性能更高。
3.5 利用之 间的隔离与通信问题
利用之间势必是要通信的。咱们用 iframe 时可能应用 postMessage、本地存储等形式。如果是同一个运行时的不同我的项目之间可能会应用 window 自定义事件,或者引入独自的事件机制等等。
因为咱们这个微前端计划技术栈是对立的,人造通信就十分不便,挂载一个全局的 vue 事件机制、全局 store 就能实现通信。
利用的格局次要是 window 全局对象上属性的隔离、本地存储隔离、全局款式隔离。在隔离上咱们没有做的很相对,次要应用命名空间,并重约定的形式。
四、造成对立的工程化解决方案
4.1 整合所有解决方案造成命令行工具
咱们在对所有问题造成解决方案之后,为防止每次接入我的项目都反复配置设置,咱们把所有计划整合成一个命令行工具 tangram-sdk。
tangramSDK 集成了这些能力:
- 基于微前端计划的编译打包规定
- 基于微前端计划的本地开发服务规定
- 发包自动更新全局配置文件(新模块接入无需注册)
- 编译打包配置可扩大能力
- mock 数据、接口联调能力
- 初始化我的项目脚手架
- 云部署能力
在 tangram-sdk 框架根底上,咱们造成了对立的项目管理、依赖治理,公共库、ui 框架、代码标准、单元测试,构建形式。
4.2 与 CICD 集成
咱们的计划自身须要与 cicd 配合能力更高效执行各种流程。子工程须要部署在同一个目录下,部署阶段须要触发更新配置文件等。
咱们落地了基于微前端架构的我的项目流水线模板,由流水线对立解决初始化,各环境部署和公布,触发事件节点等,进步了前端同学研发效率。
4.3 对立的微前端计划反对多个产品
在爱番番团队中,咱们的微前端计划曾经落地反对了多个线上运行的产品。
五、性能优化
5.1 加载性能优化
- 微服务的形式须要有一个拜访 Gateway 配置转发规定,咱们的前端资源除入口 html 外,对立间接拜访 cdn 资源,不通过 Gateway,缩小加载过程
- 接入云原生部署,能够间接应用前端代码压缩、https 等晋升性能,cdn 形式放慢资源拜访
- 通过第三方库、组件库按需加载,iconfont 图标缩小代码体积
- 通过拆散版本变动不大的第三方资源和业务代码,设置不同缓存时长形式,晋升非首次性能
- 重点页面应用非首屏异步加载解决晋升首屏性能
- 子工程采纳预加载形式晋升页面性能。子工程加载时应用 preload 并行加载资源,晋升加载性能
5.2 运行性能优化
- 革新表格、列表等组件,应用虚构列表提醒首屏性能
- 大而长的页面应用懒加载,懒接口申请等提醒首屏性能
- 主框架层面,优先外围性能实例化,非核心性能懒实例化,放慢业务页面性能;业务组件等,外围组件同步加载,非核心组件异步加载
六、总结
咱们的微前端框架曾经落地了不短的一段时间了,线上运行也比拟安稳。当初微前端框架也有了比拟多的抉择,比方 single-spa、qiankun、webpack 模块联邦等。
与 single-spa 或 qiankun 等框架比照:
长处
1. 因为运行时只有一个 vue 实例,只有一个前端路由实例,子工程的切换性能高。
2. 因为咱们对立的技术栈和繁多实例,咱们的组件复用性更高,在运行时,咱们的公共模块只须要初始化一次,比方申请、公共组件。
3. 基于第二点起因,开发人员在不同业务之间的切换成本低。
4. 因为全局的版本保护文件自增规定,新增模块不须要额定在主工程注册,流水线主动减少版本。
毛病
因为咱们框架是繁多实例的,一个比较突出的问题是不利于技术的更新和演进。
咱们打算中的革新计划,将以乾坤框架为根底,解决繁多实例的技术演进问题,并放弃既有代码的稳固,能逐渐迁徙新技术,同时在资源复用、组件复用上找到一个比拟优化的计划。
———- END ———-
举荐浏览:
云原生时代的搜寻服务算力治理
浅谈小程序开源业务架构建设之路
百度小程序包流式下载安装优化
前端工程化之 FaaS SSR 计划
日志中台不重不丢实现浅谈
百度 ToB 垂类账号权限平台的设计与实际