Skip to content

nuxt-icon can cause serious memory leaks. #62

Description

@yaowangmx

Describe the bug
nuxt-icon can cause serious memory leaks.

To Reproduce

Build and run the Nuxt 3 project, then perform load testing:

  1. Build:

    pnpm build
  2. Run server:

    node .output/server/index.mjs
  3. 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.

TestMemory Usage
Initial25.1M
After 1st load test37.0M
After 2nd44.6M
After 3rd39.7M
After 4th40.3M
After 5th39.9M
After 6th40.2M
After 5 minutes40.2M

2. Restore part of the code + enable nuxt-icons

Memory usage increases dramatically and leads to OOM after several rounds.

TestMemory Usage
Initial20.2M
After 1st load test1378.4M
After 2nd2643.6M
After 3rd3678.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.

TestMemory Usage
Initial20.9M
After 1st load test38.6M
After 2nd39.9M
After 3rd40.6M
After 4th41.5M
After 5th41.5M
After 6th41.9M
After 5 minutes41.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:

  1. 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
    
  2. Removed the vue-sonner package or commented out related code
    (This also reduced memory growth.)

  3. Updated nuxt.config.js according to the version changes above
    (Some modules required different configuration formats.)

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

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions