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

SSR without NODE_ENV loads devtools and causes memory leak #1841

Open
4 tasks done
yooouuri opened this issue May 6, 2024 · 6 comments
Open
4 tasks done

SSR without NODE_ENV loads devtools and causes memory leak #1841

yooouuri opened this issue May 6, 2024 · 6 comments
Labels
❗ p4-important Priority 4: bugs that violate documented behavior, or significantly impact perf Type: Bug Bug or Bug fixes

Comments

@yooouuri
Copy link

yooouuri commented May 6, 2024

Reporting a bug?

The global __VUE_DEVTOOLS_PLUGINS__ array expands on every request, thus creates a memory leak.

Also when the project is build with mode = production, should NODE_ENV=production still be needed?

Expected behavior

__VUE_DEVTOOLS_PLUGINS__ should not be present when vite builds with production and there should be no memory leak.

Reproduction

git clone [email protected]:yooouuri/devtools-memory-leak-ssr-vue-i18n.git
cd devtools-memory-leak-ssr-vue-i18n
pnpm install
pnpm run build

Run without NODE_ENV=production and with

node server.js

...

NODE_ENV=production node server.js

System Info

System:
    OS: macOS 14.4.1
    CPU: (8) arm64 Apple M1 Pro
    Memory: 55.30 MB / 16.00 GB
    Shell: 5.9 - /bin/zsh
  Binaries:
    Node: 18.15.0 - ~/.nvm/versions/node/v18.15.0/bin/node
    Yarn: 1.22.22 - /opt/homebrew/bin/yarn
    npm: 9.5.0 - ~/.nvm/versions/node/v18.15.0/bin/npm
  Browsers:
    Firefox: 123.0.1
    Safari: 17.4.1
  npmPackages:
    @intlify/unplugin-vue-i18n: ^4.0.0 => 4.0.0 
    @vitejs/plugin-vue: ^5.0.4 => 5.0.4 
    vite: ^5.2.11 => 5.2.11 
    vue: ^3.4.21 => 3.4.26 
    vue-i18n: ^9.13.1 => 9.13.1 
    vue-router: ^4.3.0 => 4.3.2

Screenshot

image (11)
image (12)

Additional context

global without NODE_ENV=production

<ref *1> Object [global] {
  global: [Circular *1],
  queueMicrotask: [Function: queueMicrotask],
  clearImmediate: [Function: clearImmediate],
  setImmediate: [Function: setImmediate] {
    [Symbol(nodejs.util.promisify.custom)]: [Getter]
  },
  structuredClone: [Function: structuredClone],
  clearInterval: [Function: clearInterval],
  clearTimeout: [Function: clearTimeout],
  setInterval: [Function: setInterval],
  setTimeout: [Function: setTimeout] {
    [Symbol(nodejs.util.promisify.custom)]: [Getter]
  },
  atob: [Function: atob],
  btoa: [Function: btoa],
  performance: Performance {
    nodeTiming: PerformanceNodeTiming {
      name: 'node',
      entryType: 'node',
      startTime: 0,
      duration: 7916.673583984375,
      nodeStart: 3.252792000770569,
      v8Start: 5.740541934967041,
      bootstrapComplete: 21.964874982833862,
      environment: 12.48104190826416,
      loopStart: 28.598249912261963,
      loopExit: -1,
      idleTime: 7167.902995
    },
    timeOrigin: 1714996826399.443
  },
  fetch: [AsyncFunction: fetch],
  __VUE_HMR_RUNTIME__: {
    createRecord: [Function (anonymous)],
    rerender: [Function (anonymous)],
    reload: [Function (anonymous)]
  },
  __VUE_INSTANCE_SETTERS__: [ [Function (anonymous)], [Function (anonymous)] ],
  __VUE_SSR_SETTERS__: [ [Function (anonymous)], [Function (anonymous)] ],
  __INTLIFY__: true,
  __INTLIFY_PROD_DEVTOOLS__: false,
  __INTLIFY_JIT_COMPILATION__: false,
  __INTLIFY_DROP_MESSAGE_COMPILER__: false,
  __VUE_PROD_DEVTOOLS__: false,
  __VUE__: true,
  __VUE_DEVTOOLS_PLUGINS__: [
    {
      pluginDescriptor: [Object],
      setupFn: [Function (anonymous)],
      proxy: null
    }
  ]
}

with NODE_ENV=production

<ref *1> Object [global] {
  global: [Circular *1],
  queueMicrotask: [Function: queueMicrotask],
  clearImmediate: [Function: clearImmediate],
  setImmediate: [Function: setImmediate] {
    [Symbol(nodejs.util.promisify.custom)]: [Getter]
  },
  structuredClone: [Function: structuredClone],
  clearInterval: [Function: clearInterval],
  clearTimeout: [Function: clearTimeout],
  setInterval: [Function: setInterval],
  setTimeout: [Function: setTimeout] {
    [Symbol(nodejs.util.promisify.custom)]: [Getter]
  },
  atob: [Function: atob],
  btoa: [Function: btoa],
  performance: Performance {
    nodeTiming: PerformanceNodeTiming {
      name: 'node',
      entryType: 'node',
      startTime: 0,
      duration: 5379.410166025162,
      nodeStart: 10.831707954406738,
      v8Start: 14.853625059127808,
      bootstrapComplete: 31.616665959358215,
      environment: 23.72316598892212,
      loopStart: 34.85424995422363,
      loopExit: -1,
      idleTime: 5130.530334
    },
    timeOrigin: 1714993597746.848
  },
  fetch: [AsyncFunction: fetch],
  __VUE_INSTANCE_SETTERS__: [ [Function (anonymous)] ],
  __VUE_SSR_SETTERS__: [ [Function (anonymous)] ],
  __VUE_PROD_DEVTOOLS__: false,
  __INTLIFY_PROD_DEVTOOLS__: false,
  __VUE__: true
}

Validations

@yooouuri yooouuri added the Status: Review Needed Request for review comments label May 6, 2024
kazupon added a commit that referenced this issue May 7, 2024
kazupon added a commit that referenced this issue May 7, 2024
@kazupon kazupon added Type: Bug Bug or Bug fixes ❗ p4-important Priority 4: bugs that violate documented behavior, or significantly impact perf and removed Status: Review Needed Request for review comments labels May 7, 2024
@kazupon
Copy link
Member

kazupon commented May 7, 2024

I've fixed this issue.
You can install nightly version.

"vue-i18n": "npm:[email protected]",

@kazupon
Copy link
Member

kazupon commented May 7, 2024

one more thing.
You need to put ssr option in vite.config.ts
https://github.com/intlify/bundle-tools/tree/main/packages/unplugin-vue-i18n#ssr

@yooouuri
Copy link
Author

yooouuri commented May 7, 2024

one more thing. You need to put ssr option in vite.config.ts https://github.com/intlify/bundle-tools/tree/main/packages/unplugin-vue-i18n#ssr

Oops I forgot to add it in my reproducible example.

Im going to test it, thanks!

@yooouuri
Copy link
Author

yooouuri commented May 7, 2024

@kazupon yooouuri/devtools-memory-leak-ssr-vue-i18n@bf19ff2

"vue-i18n": "npm:[email protected]"

vite config

export default defineConfig(({ isSsrBuild }) => {
  ...
  VueI18nPlugin({
    include: [path.resolve(__dirname, './src/locales/**')],
    ssr: isSsrBuild ?? false,
  }),
  ...
})

Added a console.log({ NODE_ENV: process.env.NODE_ENV }) to server.js and set isProd to true.

{ NODE_ENV: undefined }
http://localhost:6173
<ref *1> Object [global] {
  global: [Circular *1],
  queueMicrotask: [Function: queueMicrotask],
  clearImmediate: [Function: clearImmediate],
  setImmediate: [Function: setImmediate] {
    [Symbol(nodejs.util.promisify.custom)]: [Getter]
  },
  structuredClone: [Function: structuredClone],
  clearInterval: [Function: clearInterval],
  clearTimeout: [Function: clearTimeout],
  setInterval: [Function: setInterval],
  setTimeout: [Function: setTimeout] {
    [Symbol(nodejs.util.promisify.custom)]: [Getter]
  },
  atob: [Function: atob],
  btoa: [Function: btoa],
  performance: Performance {
    nodeTiming: PerformanceNodeTiming {
      name: 'node',
      entryType: 'node',
      startTime: 0,
      duration: 2640.751667022705,
      nodeStart: 3.6312090158462524,
      v8Start: 6.716041922569275,
      bootstrapComplete: 22.280874967575073,
      environment: 13.79841697216034,
      loopStart: 25.462584018707275,
      loopExit: -1,
      idleTime: 2420.212333
    },
    timeOrigin: 1715067688929.66
  },
  fetch: [AsyncFunction: fetch],
  __VUE_HMR_RUNTIME__: {
    createRecord: [Function (anonymous)],
    rerender: [Function (anonymous)],
    reload: [Function (anonymous)]
  },
  __VUE_INSTANCE_SETTERS__: [ [Function (anonymous)], [Function (anonymous)] ],
  __VUE_SSR_SETTERS__: [ [Function (anonymous)], [Function (anonymous)] ],
  __VUE_PROD_DEVTOOLS__: false,
  __INTLIFY_PROD_DEVTOOLS__: false,
  __VUE__: true
}

@yooouuri
Copy link
Author

yooouuri commented May 7, 2024

@kazupon but if you change isProd to false in https://github.com/yooouuri/devtools-memory-leak-ssr-vue-i18n/blob/main/server.js#L11

And run node server.js, the __VUE_DEVTOOLS_PLUGINS__ array is getting populated, on every request. This will result in a memory leak.

First time:

image

After a few refreshes:

image

Copy link
Member

kazupon commented May 8, 2024

but if you change isProd to false in

That is because you have set the flag to development instead of production. That is why ssr in unplugin-vue-i18n in vite.config.ts is not set to true.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
❗ p4-important Priority 4: bugs that violate documented behavior, or significantly impact perf Type: Bug Bug or Bug fixes
Projects
None yet
Development

No branches or pull requests

2 participants