From bee0c91179756dfef456b80628b312f12e9b6ffe Mon Sep 17 00:00:00 2001 From: maoger Date: Sun, 27 Sep 2026 09:05:04 +0800 Subject: [PATCH] fix(client): avoid retaining onContentUpdated callbacks during ssr `onContentUpdated` adds the callback to a module-level Set and relies on `onUnmounted` to remove it. During `vuepress build`, every page is rendered with the same server app, and components are never unmounted in SSR, so every callback registered while rendering stays in the Set until the process exits. Each callback closure usually captures component state, which keeps the component instance and, through `parent` / `subTree`, the whole component and vnode tree of the rendered page alive. As a result, the memory used by the build grows linearly with the number of pages, and large sites may run out of memory while rendering. Content updated callbacks are only invoked on client side, so skip the registration in SSR. The rendered HTML is unchanged. --- packages/client/src/composables/onContentUpdated.ts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/packages/client/src/composables/onContentUpdated.ts b/packages/client/src/composables/onContentUpdated.ts index 90cf68bce1..88903f7feb 100644 --- a/packages/client/src/composables/onContentUpdated.ts +++ b/packages/client/src/composables/onContentUpdated.ts @@ -8,6 +8,10 @@ import type { ContentUpdatedCallback } from '../types/index.js' * in the DOM. */ export const onContentUpdated = (fn: ContentUpdatedCallback): void => { + // callbacks are only invoked on client side, and components are never + // unmounted in ssr, so skip registering to avoid retaining them forever + if (__VUEPRESS_SSR__) return + contentUpdatedCallbacks.add(fn) onUnmounted(() => { contentUpdatedCallbacks.delete(fn)