Memory leak in hoist static
Version
3.2.26
Reproduction link
Steps to reproduce
- Open dist/index.html
- Click click button three times.
- Open memory panel in chrome devtools, then take heap snapshot, then search BigData。
What is expected?
old component instance can reacyled
What is actually happening?
old component instance not reacyled
静态节点优化会在闭包中创建一个 hoisted${num} 的变量,之后渲染时,会将 hoisted.el 设置为dom。假如此组件中有事件监听,则会造成实例无法回收,从而造成内存泄漏。
Static hoist will creates a hoisted variable in the closure, and later sets dom to hoisted.el when rendering. If there are event listeners in the component, the component instance cannot be recycled, resulting in a memory leak.
This only keeps the first component instance in memory, so it's technically not a memory leak because the total memory won't increase over time. It's still inefficient though and can be improved.
I also ran into this issue while trying to fix a memory leak. It's quite inconvenient while hunting for leaks, as it's something that will get you on the wrong track. Glad to know this now..
You can temporarily circumvent this problem by using the following methods
vue-cli:
chainWebpack: (config) => {
config.module
.rule('vue')
.use('vue-loader')
.tap((options) => {
options.compilerOptions = options.compilerOptions || {};
options.compilerOptions.hoistStatic = false;
return options;
});
},
Thanks. For vite you can use:
plugins: [vue({ template: { compilerOptions: { hoistStatic: false } } })],