From 2fb6bdabf03b617ccfa1d00c9261242bc5d93e56 Mon Sep 17 00:00:00 2001 From: Miroma Date: Thu, 30 Jul 2026 13:24:35 +0200 Subject: [PATCH] perf(md): limit the compile cache's memory usage add maxSize of 64MB to the markdown compile result LRUCache, such that large pages do not grow this cache unboundedly. change the cache key from JSON.stringify({ src, ts, relativePath }) (which not only included the entire source of each file in each key, but also instantiated an object and called JSON.stringify), to a simpler string concatenation with the sha256 hash of src. Co-authored-by: Calum H. (IMB11) Based-on-patch-by: Calum H. (IMB11) --- src/node/markdownToVue.ts | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/src/node/markdownToVue.ts b/src/node/markdownToVue.ts index a31b60c7..9cbdbd8c 100644 --- a/src/node/markdownToVue.ts +++ b/src/node/markdownToVue.ts @@ -1,5 +1,6 @@ import { resolveTitleFromToken } from '@mdit-vue/shared' import { LRUCache } from 'lru-cache' +import { hash } from 'node:crypto' import fs from 'node:fs' import path from 'node:path' import { createDebug } from 'obug' @@ -24,7 +25,12 @@ import { getGitTimestamp } from './utils/getGitTimestamp' import { processIncludes } from './utils/processIncludes' const debug = createDebug('vitepress:md') -const cache = new LRUCache({ max: 1024 }) +const cache = new LRUCache({ + maxSize: 64 * 1024 * 1024, + sizeCalculation(value, key) { + return Math.max(1, 2 * (key.length + value.vueSrc.length)) + } +}) const scriptRE = /<\/script>/ const scriptLangTsRE = /<\s*script[^>]*\blang=['"]ts['"][^>]*/ @@ -51,8 +57,7 @@ export function clearCache(relativePath?: string) { return } - relativePath = JSON.stringify({ relativePath }).slice(1) - cache.find((_, key) => key.endsWith(relativePath!) && cache.delete(key)) + cache.find((_, key) => key.endsWith(`:${relativePath}`) && cache.delete(key)) } function normalizeDriveLetter(file: string) { @@ -122,7 +127,8 @@ export async function createMarkdownToVueRenderFn( file = rewrites.get(normalizeDriveLetter(file)) || file const relativePath = slash(path.relative(srcDir, file)) - const cacheKey = JSON.stringify({ src, ts, relativePath }) + const srcHash = hash('sha256', src, 'base64url') + const cacheKey = `${srcHash}:${ts}:${relativePath}` if (options.cache !== false) { const cached = cache.get(cacheKey) if (cached) {