微前端子应用卸载后事件监听器没清除怎么办?
我在用 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);
}
resizeHandler每次mount都会被重新赋值,但qiankun卸载时可能没触发你写的unmount。来调试看看:
1. 首先确认unmount确实被调用了,在unmount里加个console.log
2. 更稳妥的写法是把handler改成引用稳定的函数:
3. 如果还不行,可能是qiankun沙箱的问题,试试在子应用生命周期里加个清理:
另外建议用window.onresize替代,这样后绑定的会覆盖之前的,不容易漏。不过要注意这种方式会覆盖其他监听。
刚又想到一个骚操作,可以在mount时先remove再add,确保唯一性。微前端这种问题太常见了,都是泪啊...
还有个坑,如果你用了 webpack 的热更新,模块会被重复加载导致
resizeHandler被重置为 null,旧的监听器就再也找不回了。开发环境记得刷新页面测试,或者干脆用事件委托的方式处理。