From f53a09739e1667ed62dfc84ef4c7afa82abfafcb 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) {