优化微应用加载
qiankun 会以流式方式处理 HTML Entry,并在解析过程中发现和预加载后续资源。大多数应用无需额外配置预取策略。优化时应优先关注入口体积、HTTP 缓存、CORS 配置和挂载方式。
建立性能基线
以 mountPromise 的完成时间作为挂载结束点,记录从开始加载到完成挂载的总耗时:
performance.mark('sub-app:start');
const microApp = loadMicroApp({
name: 'sub-app',
entry: '//localhost:7101',
container,
});
await microApp.mountPromise;
performance.measure('sub-app:mount', 'sub-app:start');同时通过浏览器的网络(Network)面板分别记录首次加载和再次挂载的数据。入口 HTML 的下载时间仅反映加载过程的一部分,不应作为唯一指标。
优化顺序
1. 配置 CORS 和 HTTP 缓存
主应用通过 fetch 获取微应用入口和资源,因此跨域服务器必须返回正确的 CORS 响应头。
对于文件名包含内容哈希的 JavaScript、CSS 和字体资源,应配置长期缓存。HTML Entry 需要及时更新,可使用协商缓存。压缩和 CDN 配置也应覆盖微应用的全部资源。
qiankun 还会在当前页面内维护一个内存 LRU 缓存,保存成功的请求结果,并按应用名称复用已卸载的实例。只有运行时缓存未命中时,HTTP 协商缓存才会参与请求;同一页面中的重新挂载不能用于刷新部署版本。如需确保加载新发布的微应用,应刷新主应用页面。
2. 保持 HTML Entry 简洁
入口中只应声明当前应用所需的资源,并且最多只能有一个脚本带有 entry 标记。官方构建插件生成的生产构建通常会为一个脚本添加 entry 属性;Vite 开发环境的 HTML 可以不包含显式标记,由 qiankun 在运行时选择导出生命周期的模块。
3. 保持应用名称稳定
同一应用再次挂载时,qiankun 按 name 和 entry 查找可复用实例:缓存命中时,即使容器是新创建的节点,也不再执行入口和 bootstrap;缓存已回收且没有其他可复用实例时,则重新加载。因此同一 name 应始终指向同一个应用,不要在每次渲染时为同一应用生成不同的名称。空闲池的数量和时间限制见运行多个微应用实例。
需要同时运行多个实例时,每个实例都应使用独立容器,具体要求见多实例指南。
4. 在 mount 中创建实例状态
重新挂载可能复用缓存,也可能在缓存回收后重新加载。应用实例、路由实例和实例级状态容器应在 mount() 中创建,并在 unmount() 中销毁,不应依赖模块顶层代码的执行次数。按照此方式管理状态,可以避免复用加载结果时残留旧状态或丢失样式。
5. 谨慎覆盖 fetch
仅在身份认证、代理或可观测性等场景确有需要时配置自定义 fetch。自定义实现必须保持标准 Fetch API 的响应类型和流式语义,不应预先将响应读取为字符串,也不应移除缓存响应头。
完整字段见 AppConfiguration.fetch。
不应沿用 2.x 的预取配置
- 不应调用
start({ prefetch: ... });v3 的start()不接收此类配置。 prefetchApps已废弃,不应成为新项目的默认优化手段。- 不应仅为预加载资源而提前创建一个不执行卸载的
loadMicroApp实例。
仅当性能数据表明按需加载无法满足目标时,才应在业务层提前触发应用加载,并同时设计取消和卸载机制。
使用网络面板定位瓶颈
建议按照以下顺序检查:
- HTML Entry 是否被重定向、身份认证或 CORS 阻塞。
- 关键 JS/CSS 是否缺少压缩或合理缓存头。
- 是否存在重复下载、体积过大的源码映射(source map)或无关资源。
- 再次挂载时是否仍产生完整的网络请求瀑布。
mountPromise的主要耗时来自网络、脚本执行,还是微应用自身的渲染。
如果网络请求耗时较短,但 mountPromise 仍耗时较长,则瓶颈通常位于微应用的初始化或首次渲染过程,而非 qiankun 加载器。
相关内容
- HTML Entry——加载流程及其外部表现
- 处理微应用错误——处理资源加载失败
- AppConfiguration——自定义
fetch与高级选项 - HTML Entry 流式加载原理——面向贡献者的实现细节
