nuxt / bridge

🌉 Experience Nuxt 3 features on existing Nuxt 2 projects
MIT License
273 stars 29 forks source link

Huge Memory leak If the "meta" option is set true #94

Closed antlionguard closed 2 years ago

antlionguard commented 2 years ago

Environment


Reproduction

Here's my package json

{
  "name": "XXXX",
  "version": "1.0.0",
  "description": "XXXX website.",
  "author": "XXXX",
  "private": true,
  "scripts": {
    "dev": "nuxi dev",
    "build": "nuxi build",
    "start": "nuxt start"
  },
  "dependencies": {
    "@nuxtjs/axios": "^5.13.6",
    "@nuxtjs/gtm": "^2.4.0",
    "@nuxtjs/i18n": "^7.2.0",
    "@nuxtjs/proxy": "^2.1.0",
    "@nuxtjs/sentry": "^5.1.6",
    "@nuxtjs/style-resources": "^1.2.1",
    "@pinia/nuxt": "^0.1.8",
    "@types/file-saver": "^2.0.3",
    "@types/sass-loader": "^8.0.2",
    "@vueuse/core": "^7.4.0",
    "ant-design-vue": "^1.7.8",
    "awesome-phonenumber": "^2.65.0",
    "axios-extensions": "^3.1.3",
    "browser-image-compression": "^1.0.14",
    "cookie-universal-nuxt": "^2.1.5",
    "core-js": "^3.20.1",
    "date-fns": "^2.27.0",
    "file-saver": "^2.0.5",
    "filepond": "^4.30.3",
    "filepond-plugin-file-validate-size": "^2.2.5",
    "filepond-plugin-file-validate-type": "^1.2.6",
    "filepond-plugin-image-preview": "^4.6.10",
    "google-libphonenumber": "^3.2.26",
    "jquery": "^3.5.1",
    "js-cookie": "^3.0.1",
    "jwt-decode": "^3.1.2",
    "lodash": "^4.17.21",
    "moment": "^2.29.1",
    "nuxt-buefy": "^0.3.31",
    "nuxt-edge": "latest",
    "nuxt-sweetalert2": "^1.0.0",
    "pinia": "2.0.11",
    "sweetalert2": "^11.3.0",
    "swiper": "^7.4.1",
    "unplugin-vue2-script-setup": "0.9.1",
    "vee-validate": "^3.4.14",
    "vue-advanced-cropper": "^1.8.2",
    "vue-awesome-swiper": "^4.1.1",
    "vue-cropperjs": "4.2.0",
    "vue-demi": "^0.12.1",
    "vue-filepond": "^7.0.2",
    "vue-multiselect": "^2.1.6",
    "vue-slick-carousel": "^1.0.6",
    "vue-sweetalert2": "^5.0.2",
    "vuejs-paginate": "^2.1.0",
    "vuex-persistedstate": "^4.0.0",
    "yup": "^0.32.11"
  },
  "devDependencies": {
    "@babel/eslint-parser": "^7.16.5",
    "@nuxt/bridge": "npm:@nuxt/bridge-edge",
    "@nuxt/types": "^2.15.8",
    "@nuxt/typescript-build": "^2.1.0",
    "@nuxtjs/dotenv": "^1.4.1",
    "@nuxtjs/eslint-config": "^8.0.0",
    "@nuxtjs/eslint-config-typescript": "^8.0.0",
    "@nuxtjs/eslint-module": "^3.0.2",
    "@nuxtjs/tailwindcss": "^4.2.1",
    "@types/google-libphonenumber": "^7.4.23",
    "@types/js-cookie": "^3.0.1",
    "@types/lodash": "^4.14.178",
    "@types/lodash-webpack-plugin": "^0.11.6",
    "@types/vue-cropperjs": "^4.1.2",
    "@typescript-eslint/eslint-plugin": "^5.8.0",
    "@typescript-eslint/parser": "^5.8.0",
    "@vue/runtime-dom": "^3.2.26",
    "babel-eslint": "^10.1.0",
    "babel-plugin-lodash": "^3.3.4",
    "eslint": "^8.5.0",
    "eslint-plugin-import": "^2.25.3",
    "eslint-plugin-nuxt": "^3.1.0",
    "eslint-plugin-vue": "^8.2.0",
    "eslint-webpack-plugin": "^3.1.1",
    "lodash-webpack-plugin": "^0.11.6",
    "node-sass": "^4.14.1",
    "sass-loader": "^10.1.1",
    "ts-loader": "9.2.6",
    "typescript": "^4.4.4",
    "vue-eslint-parser": "^8.0.1"
  }
}

Starting procedure

Describe the bug

If the "meta" option is set true memory usage exceeds 2000mb and the application crashes.

Additional context

No response

Logs

No response

phoenix-ru commented 2 years ago

Is there any more information other than package json?

I am investigating a similar issue but not sure where does it originate. As far as I noticed by running heap profiler, the most amount of memory is consumed by marking nuxt reactive and not doing the clean-up. This is the code I've been pointed at which does significant memory allocations:

beforeCreate() {
  vue2_bridge["default"].util.defineReactive(this, "nuxt", this.$root.$options.nuxt);
}

This is coming somewhere from the Nuxt component. Definitely not a good idea to mark something reactive over and over again without memory clean-up.

Additionally, I noticed that the flame graphs make a monstrous amount of n and wt.next calls (not sure what those mean) from chunks/app/vue2.mjs which are always followed by Vue3._render -> Vue3._init -> toVue3ComponentInstance (even though it's still Vue 2).

Currently this is a critical issue, as rendering a very simple page consisting of header/footer and client-only-rendered content allocates 270 MB of memory. This makes a production application restart every 20 minutes with container limit of 4 GB (which corresponds to about 2K requests when stress-testing).

I honestly don't understand why is there reactivity on SSR?

antlionguard commented 2 years ago

I tried with @nuxt/bridge-edge@3.0.0-27446026.a5e19b1 but my application still crashing due to high memory usage.

Extra: I removed all useMeta({...}) functions in my code and i tried again it still crashes. I mean i only set the meta option true.

resim resim

Am I doing something wrong? @danielroe

@phoenix-ru i think there's no extra information need for now(maybe nuxt.config?). because i just only set the meta option true and i didn't use "useMeta" nowhere and the problem still exist.

phoenix-ru commented 2 years ago

@antlionguard I was somehow able to get it running without memory leak after the recent commits. However, I can't reproduce it and memory leak is back. It is not that obvious what is leaking now, as reactivity allocations are gone from heap profile and server can now handle 3K requests instead of 2K.

What I still don't understand though is why simple rendering of Vue SSR causes so much recursive calls (again, originating from /chunks/app/vue2.mjs. I think I'll have to build it with source maps or without some terser optimizations...

danielroe commented 2 years ago

Yes, we resolved a memory leak in the linked PR. The current leak is due to using a Vue 3 library (vueuse/head) and registering it per request if meta: true. In Vue 2, there is a global Vue instance shared between requests.

antlionguard commented 2 years ago

Hello, it's me again :(

I tried again with new version after nuxt/framework#3898 pr. The problem still exist when i set meta option true.

resim resim

nuxt.config.ts bridge settings.

bridge: {
    autoImports: true,
    nitro: false,
    meta: true
}

My @nuxt/bridge-edge version from yarn.lock

"@nuxt/bridge@npm:@nuxt/bridge-edge":
  version "3.0.0-27470162.e34ed88"
  resolved "https://registry.yarnpkg.com/@nuxt/bridge-edge/-/bridge-edge-3.0.0-27470162.e34ed88.tgz#5627c7111b4721f365dc53efca05197ff68ee722"
  integrity sha512-qyeZ52UyQ16rO62P7QN3ayCDZqvvwm4P0s6mxU+h0Fz2q8m2GbsaKOd3lhPJUWicXvrL68++F7SlyAbCcn+6NQ==
  dependencies:
    "@babel/plugin-proposal-nullish-coalescing-operator" "^7.16.7"
    "@babel/plugin-proposal-optional-chaining" "^7.16.7"
    "@babel/plugin-transform-typescript" "^7.16.8"
    "@nuxt/kit" "npm:@nuxt/kit-edge@3.0.0-27470162.e34ed88"
    "@nuxt/nitro" "npm:@nuxt/nitro-edge@3.0.0-27470162.e34ed88"
    "@nuxt/postcss8" "^1.1.3"
    "@nuxt/schema" "npm:@nuxt/schema-edge@3.0.0-27470162.e34ed88"
    "@vitejs/plugin-legacy" "^1.7.1"
    "@vue/composition-api" "^1.4.9"
    "@vueuse/head" "^0.7.5"
    acorn "^8.7.0"
    cookie-es "^0.5.0"
    defu "^6.0.0"
    destr "^1.1.0"
    enhanced-resolve "^5.9.2"
    escape-string-regexp "^5.0.0"
    estree-walker "^3.0.1"
    externality "^0.2.1"
    fs-extra "^10.0.1"
    globby "^13.1.1"
    h3 "^0.4.2"
    hash-sum "^2.0.0"
    knitwork "^0.1.1"
    magic-string "^0.26.1"
    mlly "^0.4.3"
    murmurhash-es "^0.1.1"
    node-fetch "^3.2.3"
    nuxi "npm:nuxi-edge@3.0.0-27470162.e34ed88"
    ohash "^0.1.0"
    pathe "^0.2.0"
    perfect-debounce "^0.1.3"
    postcss "^8"
    postcss-import "^14.1.0"
    postcss-import-resolver "^2.0.0"
    postcss-preset-env "^7.4.3"
    postcss-url "^10.1.3"
    scule "^0.2.1"
    semver "^7.3.5"
    ufo "^0.8.1"
    unimport "^0.1.3"
    unplugin "^0.6.0"
    unplugin-vue2-script-setup "^0.10.0"
    untyped "^0.4.3"
    vite "^2.8.6"
    vite-plugin-vue2 "^1.9.3"
    vue-template-compiler "^2.6.14"

Is there an extra information you want from me? @danielroe @pi0

danielroe commented 2 years ago

@antlionguard Thanks - following up with a PR on that mixin: https://github.com/nuxt/framework/pull/3900.

antlionguard commented 2 years ago

@antlionguard Thanks - following up with a PR on that mixin: nuxt/framework#3900.

There's something broke after this PR. I got this error in my all pages.

resim

Should i open new issue for these errors?

danielroe commented 2 years ago

@antlionguard Yes please. 🙏