perf(md): bypass gray-matter's unbounded cache

gray-matter memoizes every parsed result in a plain cache object keyed
by the full input string, except when it is passed an options object.

310f934938/index.js (L44-L47)

such cache is never bounded, or cleared, so on large sites memory usage
skyrockets.

with this change, we are always passing an empty options object on every
call to matter() to bypass its internal cache.

Co-authored-by: Calum H. (IMB11) <contact@cal.engineer>
Original-patch-by: Calum H. (IMB11) <contact@cal.engineer>
pull/5347/head
Miroma 1 month ago committed by Divyansh Singh
parent 515933bc5f
commit 4f8703d61c

@ -510,6 +510,10 @@ export async function createMarkdownRenderer(
if (options.component !== false) { if (options.component !== false) {
componentPlugin(md, normalizePluginOptions(options.component)) componentPlugin(md, normalizePluginOptions(options.component))
} }
// pass an empty options object to gray-matter, otherwise it would memoize
// the results in an unbounded cache, where the key is the full file content.
// https://github.com/jonschlinkert/gray-matter/blob/310f9349381775d10a221cef903989eb5acc8843/index.js#L44-L47
;(options.frontmatter ??= {}).grayMatterOptions ??= {}
frontmatterPlugin(md, options.frontmatter) frontmatterPlugin(md, options.frontmatter)
if (options.headers) { if (options.headers) {
headersPlugin(md, { headersPlugin(md, {

@ -53,7 +53,7 @@ export function processIncludes(
// region not found, it might be a header // region not found, it might be a header
const headerContent = const headerContent =
path.extname(includePath) === '.md' path.extname(includePath) === '.md'
? matter(content).content ? matter(content, {}).content
: content : content
const headerLines = headerContent.split(/\r?\n/) const headerLines = headerContent.split(/\r?\n/)
const tokens = md const tokens = md
@ -95,7 +95,7 @@ export function processIncludes(
} }
if (!hasMeta && path.extname(includePath) === '.md') { if (!hasMeta && path.extname(includePath) === '.md') {
content = matter(content).content content = matter(content, {}).content
} }
includes.push(slash(includePath)) includes.push(slash(includePath))

Loading…
Cancel
Save