Describe the bug
nuxt-icon can cause serious memory leaks.
To Reproduce
Build and run the Nuxt 3 project, then perform load testing:
-
Build:
-
Run server:
node .output/server/index.mjs
-
Load test using autocannon:
npx autocannon -c 40 -d 30 http://localhost:3000
1. With index.vue reduced to only a single <div>
Memory remains stable.
| Test |
Memory Usage |
| Initial |
25.1M |
| After 1st load test |
37.0M |
| After 2nd |
44.6M |
| After 3rd |
39.7M |
| After 4th |
40.3M |
| After 5th |
39.9M |
| After 6th |
40.2M |
| After 5 minutes |
40.2M |
2. Restore part of the code + enable nuxt-icons
Memory usage increases dramatically and leads to OOM after several rounds.
| Test |
Memory Usage |
| Initial |
20.2M |
| After 1st load test |
1378.4M |
| After 2nd |
2643.6M |
| After 3rd |
3678.1M |
At the 4th test, the following error appears in the console:
<--- Last few GCs --->
[30424:0000014AD5201000] 272236 ms: Mark-Compact 4014.8 (4129.0) -> 3994.8 (4124.8) MB, pooled: 0 MB, 853.34 / 0.02 ms (average mu = 0.214, current mu = 0.059) allocation failure; scavenge might not succeed
[30424:0000014AD5201000] 273138 ms: Mark-Compact 4013.8 (4128.0) -> 3993.9 (4124.0) MB, pooled: 0 MB, 869.00 / 0.01 ms (average mu = 0.131, current mu = 0.036) allocation failure; scavenge might not succeed
<--- JS stacktrace --->
FATAL ERROR: Ineffective mark-compacts near heap limit Allocation failed - JavaScript heap out of memory
3. Remove nuxt-icons
Memory becomes stable again.
| Test |
Memory Usage |
| Initial |
20.9M |
| After 1st load test |
38.6M |
| After 2nd |
39.9M |
| After 3rd |
40.6M |
| After 4th |
41.5M |
| After 5th |
41.5M |
| After 6th |
41.9M |
| After 5 minutes |
41.9M |
package.json
{ "name": "nuxt-app", "private": true, "type": "module", "scripts": { "build": "nuxt build --dotenv .env.prod", "dev": "nuxt dev --host --dotenv .env.dev" }, "dependencies": { "@element-plus/icons-vue": "^2.3.1", "@element-plus/nuxt": "^1.0.8", "@floating-ui/dom": "1.6.0", "@internationalized/date": "^3.8.1", "@nuxtjs/i18n": "^8.5.6", "@tailwindcss/vite": "^4.1.5", "@tanstack/vue-table": "^8.21.3", "@tato30/vue-pdf": "^1.11.4", "@types/file-saver": "^2.0.7", "@unhead/vue": "1.10.4", "@vee-validate/zod": "^4.15.0", "@vueuse/core": "^13.4.0", "@zadigetvoltaire/nuxt-gtm": "^0.0.13", "alfaaz": "^1.1.0", "class-variance-authority": "^0.7.1", "dayjs": "^1.11.13", "dayjs-nuxt": "2.1.11", "echarts": "^5.6.0", "element-plus": "^2.6.3", "file-saver": "^2.0.5", "js-md5": "^0.7.3", "jspdf": "2.5.1", "katex": "^0.16.22", "lodash": "^4.17.21", "lucide-vue-next": "^0.508.0", "mupdf-webviewer": "^0.9.1", "nprogress": "^0.2.0", "nuxt": "3.18.1", "pinia": "^2.2.1", "reka-ui": "2.2.1", "rollup-plugin-visualizer": "^5.14.0", "shadcn-nuxt": "^2.1.0", "spark-md5": "^3.0.2", "tailwind-merge": "^3.2.0", "tailwindcss": "^4.1.10", "tippy.js": "^6.3.7", "tw-animate-css": "^1.2.9", "vee-validate": "^4.15.0", "vite-plugin-compression": "^0.5.1", "vite-plugin-imagemin": "^0.6.1", "vue": "^3.5.16", "vue-router": "^4.5.1", "vue-sonner": "^2.0.0", "vue3-google-login": "2.0.29", "y-protocols": "^1.0.6", "yjs": "^13.6.27" }, "devDependencies": { "@iconify/utils": "^3.1.0", "@nuxtjs/tailwindcss": "^6.12.1", "@pinia-plugin-persistedstate/nuxt": "^1.2.1", "@pinia/nuxt": "^0.5.3", "@vitejs/plugin-vue-jsx": "^4.1.2", "sass": "^1.77.8", "typescript": "^5.9.2", "vite-svg-loader": "^5.1.0", "xlsx": "^0.16.1" }, "pnpm": { "overrides": { "jiti": "^2.5.1", "vite": "^7.0.6", "prosemirror-model": "1.19.0", "vue": "3.5.16", "@vue/compiler-sfc": "3.5.16", } }, "resolutions": { "vue": "3.5.16", "@vue/compiler-sfc": "3.5.16" } }
Troubleshooting Attempts
I tried multiple dependency and configuration adjustments. The following steps showed noticeable improvements and prevented the memory leak crash:
-
Downgraded / adjusted several package versions (effective):
nuxt: 3.12.4
vue: 3.5.13
@nuxtjs/i18n: ^8.3.0
nuxt-icons: ^3.2.1
reka-ui: 2.0.0
shadcn-nuxt: 2.0.0
@pinia-plugin-persistedstate/nuxt: ^1.2.1
-
Removed the vue-sonner package or commented out related code
(This also reduced memory growth.)
-
Updated nuxt.config.js according to the version changes above
(Some modules required different configuration formats.)
-
Performed load testing using:
npx autocannon -c 40 -d 60 \
-H "Authorization: Basic cGlwaWFkczoxMjMzMjFzdW4=" \
https://XXXX.com
Results After Adjustments
The memory was successfully released during and after stress testing, and the server no longer crashed due to out-of-memory errors.
Describe the bug
nuxt-icon can cause serious memory leaks.
To Reproduce
Build and run the Nuxt 3 project, then perform load testing:
Build:
Run server:
Load test using autocannon:
1. With
index.vuereduced to only a single<div>Memory remains stable.
2. Restore part of the code + enable
nuxt-iconsMemory usage increases dramatically and leads to OOM after several rounds.
At the 4th test, the following error appears in the console:
3. Remove
nuxt-iconsMemory becomes stable again.
package.json
{ "name": "nuxt-app", "private": true, "type": "module", "scripts": { "build": "nuxt build --dotenv .env.prod", "dev": "nuxt dev --host --dotenv .env.dev" }, "dependencies": { "@element-plus/icons-vue": "^2.3.1", "@element-plus/nuxt": "^1.0.8", "@floating-ui/dom": "1.6.0", "@internationalized/date": "^3.8.1", "@nuxtjs/i18n": "^8.5.6", "@tailwindcss/vite": "^4.1.5", "@tanstack/vue-table": "^8.21.3", "@tato30/vue-pdf": "^1.11.4", "@types/file-saver": "^2.0.7", "@unhead/vue": "1.10.4", "@vee-validate/zod": "^4.15.0", "@vueuse/core": "^13.4.0", "@zadigetvoltaire/nuxt-gtm": "^0.0.13", "alfaaz": "^1.1.0", "class-variance-authority": "^0.7.1", "dayjs": "^1.11.13", "dayjs-nuxt": "2.1.11", "echarts": "^5.6.0", "element-plus": "^2.6.3", "file-saver": "^2.0.5", "js-md5": "^0.7.3", "jspdf": "2.5.1", "katex": "^0.16.22", "lodash": "^4.17.21", "lucide-vue-next": "^0.508.0", "mupdf-webviewer": "^0.9.1", "nprogress": "^0.2.0", "nuxt": "3.18.1", "pinia": "^2.2.1", "reka-ui": "2.2.1", "rollup-plugin-visualizer": "^5.14.0", "shadcn-nuxt": "^2.1.0", "spark-md5": "^3.0.2", "tailwind-merge": "^3.2.0", "tailwindcss": "^4.1.10", "tippy.js": "^6.3.7", "tw-animate-css": "^1.2.9", "vee-validate": "^4.15.0", "vite-plugin-compression": "^0.5.1", "vite-plugin-imagemin": "^0.6.1", "vue": "^3.5.16", "vue-router": "^4.5.1", "vue-sonner": "^2.0.0", "vue3-google-login": "2.0.29", "y-protocols": "^1.0.6", "yjs": "^13.6.27" }, "devDependencies": { "@iconify/utils": "^3.1.0", "@nuxtjs/tailwindcss": "^6.12.1", "@pinia-plugin-persistedstate/nuxt": "^1.2.1", "@pinia/nuxt": "^0.5.3", "@vitejs/plugin-vue-jsx": "^4.1.2", "sass": "^1.77.8", "typescript": "^5.9.2", "vite-svg-loader": "^5.1.0", "xlsx": "^0.16.1" }, "pnpm": { "overrides": { "jiti": "^2.5.1", "vite": "^7.0.6", "prosemirror-model": "1.19.0", "vue": "3.5.16", "@vue/compiler-sfc": "3.5.16", } }, "resolutions": { "vue": "3.5.16", "@vue/compiler-sfc": "3.5.16" } }Troubleshooting Attempts
I tried multiple dependency and configuration adjustments. The following steps showed noticeable improvements and prevented the memory leak crash:
Downgraded / adjusted several package versions (effective):
Removed the
vue-sonnerpackage or commented out related code(This also reduced memory growth.)
Updated
nuxt.config.jsaccording to the version changes above(Some modules required different configuration formats.)
Performed load testing using:
npx autocannon -c 40 -d 60 \ -H "Authorization: Basic cGlwaWFkczoxMjMzMjFzdW4=" \ https://XXXX.comResults After Adjustments
The memory was successfully released during and after stress testing, and the server no longer crashed due to out-of-memory errors.