ITADN
vuejs/core/Issues

SSR memory leak after a render error in a dynamic component

#15070Closedcernymatej 创建于 2026-07-11
:hammer: p3-minor-bug
C
cernymatejcommented
### Vue version 3.5.39 ### Link to minimal reproduction https://stackblitz.com/edit/vitejs-vite-qfkzyzwp?file=leak.mjs ### Steps to reproduce - download the reproduction from stackblitz (won't work there, needs to be run locally) - run `pnpm i && pnpm leak` - see the heap size & alive app instances grow with each request after the single failed render The script renders 500 fresh SSR apps, which all get garbage-collected. Then renders **one** app whose slot content throws, then renders 500 more identical healthy apps, which will never be garbage collected afterwards. A dynamic component `<component :is>` with a `<slot />` is needed for this to reproduce. Card ```vue <script setup> defineProps({ tag: { type: String, default: 'div' } }) </script> <template> <component :is="tag" class="card"> <slot /> </component> </template> ``` app: ```vue <script setup> defineProps(['payload']) // one request renders with `payload: null` → throws </script> <template> <main> <Card>{{ payload.title }}</Card> </main> </template> ``` ### What is expected? A failed `renderToString` should not affect subsequent renders and all apps rendered after it should get garbage collected. ### What is actually happening? Every app created after the single failed render is kept in memory forever. ``` --- phase 1: 500 healthy renders --- after 500: created=500 finalized=500 alive=0 heap=20.6MB --- one crashing render (SSR render error) --- render rejected as expected: Cannot read properties of null (reading 'title') --- phase 2: 500 healthy renders (identical to phase 1) --- after 500: created=1001 finalized=500 alive=501 heap=29.0MB FINAL: created=1001 finalized=500 alive=501 ``` ### System Info ```shell ``` ### Any additional comments? _No response_
关闭于 2026-07-16 2 条评论