Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Memory leak in hoist static #5256

Open
meteor199 opened this issue Jan 13, 2022 · 7 comments · May be fixed by #9219 or #10959
Open

Memory leak in hoist static #5256

meteor199 opened this issue Jan 13, 2022 · 7 comments · May be fixed by #9219 or #10959
Labels
🔨 p3-minor-bug Priority 3: this fixes a bug, but is an edge case that only affects very specific usage. 🐞 bug Something isn't working

Comments

@meteor199
Copy link

Version

3.2.26

Reproduction link

github.com

Steps to reproduce

  1. Open dist/index.html
  2. Click click button three times.
  3. 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.

@meteor199
Copy link
Author

image

@edison1105 edison1105 added the 🐞 bug Something isn't working label Jan 14, 2022
@yyx990803 yyx990803 added ❗ p4-important Priority 4: this fixes bugs that violate documented behavior, or significantly improves perf. 🔨 p3-minor-bug Priority 3: this fixes a bug, but is an edge case that only affects very specific usage. and removed ❗ p4-important Priority 4: this fixes bugs that violate documented behavior, or significantly improves perf. labels Jan 16, 2022
@yyx990803
Copy link
Member

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.

@basvanmeurs
Copy link
Contributor

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..

@meteor199
Copy link
Author

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;
      });

  },

@basvanmeurs
Copy link
Contributor

basvanmeurs commented Jul 4, 2022

Thanks. For vite you can use:

plugins: [vue({ template: { compilerOptions: { hoistStatic: false } } })],

@pengfan2013
Copy link

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.

这种场景放到动态路由上: 反复大量的不同内容的相同页面组件, 递增的量就异常可观了, 浏览器标签爆掉就非常的简单了.

@Alone-Michael
Copy link

谢谢。对于 vite 你可以使用:

plugins: [vue({ template: { compilerOptions: { hoistStatic: false } } })],

在vite.config.js 中添加报错

@sxzz sxzz linked a pull request May 17, 2024 that will close this issue
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
🔨 p3-minor-bug Priority 3: this fixes a bug, but is an edge case that only affects very specific usage. 🐞 bug Something isn't working
Projects
None yet
6 participants