微前端子应用卸载后事件监听器没清除怎么办?

梦雅 ☘︎ 阅读 32

我在用 qiankun 搭建微前端项目,子应用卸载时发现之前绑定的全局事件监听器还在,导致内存泄漏。明明在 unmount 里写了 removeEventListener,但好像没生效。

比如下面这段代码,在子应用 mount 时加了 resize 监听,卸载时也调用了移除,但切换应用几次后,控制台还是会多次打印日志:

let resizeHandler = null;

export async function mount() {
  resizeHandler = () => console.log('resized!');
  window.addEventListener('resize', resizeHandler);
}

export async function unmount() {
  window.removeEventListener('resize', resizeHandler);
}
我来解答 赞 6 收藏
二维码
手机扫码查看
2 条解答
鑫玉 ☘︎
这个问题我遇到过,典型的微前端内存泄漏坑。关键点在于你的resizeHandler每次mount都会被重新赋值,但qiankun卸载时可能没触发你写的unmount。

来调试看看:
1. 首先确认unmount确实被调用了,在unmount里加个console.log
2. 更稳妥的写法是把handler改成引用稳定的函数:

const resizeHandler = () => console.log('resized!');

export async function mount() {
window.addEventListener('resize', resizeHandler);
}

export async function unmount() {
window.removeEventListener('resize', resizeHandler);
}


3. 如果还不行,可能是qiankun沙箱的问题,试试在子应用生命周期里加个清理:

export async function unmount() {
window.removeEventListener('resize', resizeHandler);
resizeHandler = null; // 彻底释放引用
}


另外建议用window.onresize替代,这样后绑定的会覆盖之前的,不容易漏。不过要注意这种方式会覆盖其他监听。

刚又想到一个骚操作,可以在mount时先remove再add,确保唯一性。微前端这种问题太常见了,都是泪啊...
点赞
2026-03-06 23:00
书生シ迁迁
检查一下是不是多次 mount 导致的,每次 mount 都会创建新的 handler,但变量只存了最后一个引用,之前的监听器就丢掉了。

let resizeHandler = null;

export async function mount() {
// 防止重复绑定,先清理旧的
if (resizeHandler) {
window.removeEventListener('resize', resizeHandler);
}
resizeHandler = () => console.log('resized!');
window.addEventListener('resize', resizeHandler);
}

export async function unmount() {
if (resizeHandler) {
window.removeEventListener('resize', resizeHandler);
resizeHandler = null; // 清空引用,防止内存泄漏
}
}


还有个坑,如果你用了 webpack 的热更新,模块会被重复加载导致 resizeHandler 被重置为 null,旧的监听器就再也找不回了。开发环境记得刷新页面测试,或者干脆用事件委托的方式处理。
点赞 7
2026-03-01 13:12