qinkun的缓存机制也有弊端,建议官方加个参数控制

1,300 阅读4分钟

公司前端基于qiankun架构,主应用通过qiankun加载子应用,子应用也可能通过qiankun继续加载子应用,反复套娃。经过测试,不断打开子应用后,会导致内存不断上上。通过快照分析,发现内存升高的元凶是qiankun内置的# import-html-entry

import-html-entry 的作用是什么

import-html-entry 是 qiankun / single-spa 微前端生态的核心模块之一,用来:

加载远程 HTML 入口文件(entry HTML),并提取出其中的 JS / CSS / 静态资源,然后按需执行或注入。

比如:

import { importEntry } from 'import-html-entry';

const { execScripts } = await importEntry('https://wwww.石小石.com/');
const exports = await execScripts(window);

简单来说,import-html-entry 负责做三件事:

下载远程 HTML 文件

  • 使用 fetch(url) 请求远程 HTML。
  • 解析 HTML 中的 <script><link> 标签。

提取资源并缓存

  • 提取脚本与样式资源 URL。
  • 通过自定义逻辑加载(并缓存)外部脚本与样式内容。
  • <link> 替换为内联 <style>,提升加载性能。

执行脚本

  • 通过 eval 在隔离作用域中执行 JS(防止污染主应用的 window)。
  • 支持 proxy 代理对象(qiankun 沙箱核心)。
  • 支持同步、异步脚本的加载与执行顺序。

核心源码

它的 源码中包含这些关键函数:

函数名作用
importHTML(url, opts)主入口,加载远程 HTML
processTpl解析 HTML 模板,提取 script/link
_getExternalScripts加载并缓存 JS
_getExternalStyleSheets加载并缓存 CSS
_execScripts按顺序执行脚本
getExecutableScript包装脚本为沙箱可执行代码
evalCode实际执行脚本(带缓存)

缓存机制

import-html-entry 内部维护了四个全局缓存对象, 这些缓存的目的是 在同一个浏览器会话中,当多个子应用或同一个子应用多次加载同一个 URL 时,避免重复网络请求,从而加快微前端加载速度。

var styleCache = {};    // 样式字符缓存
var scriptCache = {};   // js字符缓存
var embedHTMLCache = {};// html字符缓存
var evalCache = {};     // 编译后的脚本缓存

styleCache对应源码:

scriptCache对应源码:

embedHTMLCache对应源码:

evalCache对应源码:

缓存机制在子应用多开频繁销毁创建场景中的弊端

在单实例的 qiankun 架构 中,import-html-entry 的缓存仅会存在一份,对内存的占用影响有限,缓存带来的性能收益相对较高。
但如果系统存在大量qiankun加载子应用的场景,比如要频繁打开若干子应用(类似于菜单),子应用需要频繁打开销毁(tab切换等),同时其内部的部分功能模块又会再次通过 qiankun 动态加载子应用。这种嵌套加载结构会导致 import-html-entry 在多个层级重复缓存资源,即使资源内容相同,也会被多次存储。

因此,子应用的频繁打开与卸载,会导致内存占用持续增长,从而引发明显的性能下降(国产CPU可能更明显)。

因此,移除或禁用 import-html-entry 的缓存机制,能极大缓解内存泄漏问题,提升系统在复杂场景下的运行性能与稳定性

优化方案

缓存名缓存内容缓存目的禁用影响
styleCache每个 CSS 链接的内容(文本)避免重复请求相同样式文件每次重新请求 CSS(但浏览器会命中协商缓存,影响极小)
scriptCache每个 JS 链接的内容(文本)避免重复请求相同脚本文件每次重新请求 JS(命中浏览器缓存,影响较小)
embedHTMLCache整个 HTML 模板字符串避免重复请求入口 HTML 文件每次重新请求入口文件,性能略降
evalCache每个脚本的已编译函数 (function(){...})避免多次 eval 编译同一脚本字符串,提升运行性能每次都重新 eval 解析 JS 字符串,会略微影响性能(CPU 负担)

浏览器自带的协商缓存已能高效复用 HTML、JS、CSS 资源,因此禁用 import-html-entry 的缓存逻辑几乎不影响加载性能。
evalCache 的移除可能短暂增加 CPU 开销降低性能,但整体影响可能较小,需要综合评估。

通过在 qiankun 集成层中移除多余缓存,可有效降低内存占用,缓解泄漏问题,并显著提升系统性能与稳定性。