Skip to content

Commit 6241544

Browse files
committed
perf: cap inlineMath render cache at 500 entries with LRU eviction
1 parent 41e9dc2 commit 6241544

1 file changed

Lines changed: 28 additions & 5 deletions

File tree

src/lib/utils/inlineMathRenderer.ts

Lines changed: 28 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,32 @@ export interface MathRenderResult {
1313
hasMath: boolean;
1414
}
1515

16-
/** Cached render results to avoid re-rendering unchanged content */
16+
/**
17+
* Bounded LRU cache for rendered results. Map iteration is insertion-ordered,
18+
* so we rotate hits to the back (most-recent) and evict the front (oldest)
19+
* when the cap is exceeded.
20+
*/
21+
const RENDER_CACHE_MAX = 500;
1722
const renderCache = new Map<string, MathRenderResult>();
1823

24+
function cacheGet(key: string): MathRenderResult | undefined {
25+
const value = renderCache.get(key);
26+
if (value !== undefined) {
27+
renderCache.delete(key);
28+
renderCache.set(key, value);
29+
}
30+
return value;
31+
}
32+
33+
function cacheSet(key: string, value: MathRenderResult): void {
34+
if (renderCache.has(key)) renderCache.delete(key);
35+
renderCache.set(key, value);
36+
if (renderCache.size > RENDER_CACHE_MAX) {
37+
const oldest = renderCache.keys().next().value;
38+
if (oldest !== undefined) renderCache.delete(oldest);
39+
}
40+
}
41+
1942
/**
2043
* Check if a string contains inline math delimiters
2144
*/
@@ -36,13 +59,13 @@ export async function renderInlineMath(text: string): Promise<MathRenderResult>
3659
}
3760

3861
// Check cache
39-
const cached = renderCache.get(text);
62+
const cached = cacheGet(text);
4063
if (cached) return cached;
4164

4265
// Check if there's any math to render
4366
if (!containsMath(text)) {
4467
const result = { html: escapeHtml(text), hasMath: false };
45-
renderCache.set(text, result);
68+
cacheSet(text, result);
4669
return result;
4770
}
4871

@@ -69,7 +92,7 @@ export async function renderInlineMath(text: string): Promise<MathRenderResult>
6992
// Actually we need to be more careful - escape text first, then insert math
7093

7194
const result = { html, hasMath };
72-
renderCache.set(text, result);
95+
cacheSet(text, result);
7396
return result;
7497
}
7598

@@ -78,7 +101,7 @@ export async function renderInlineMath(text: string): Promise<MathRenderResult>
78101
* Returns null if not cached (caller should use async version)
79102
*/
80103
export function renderInlineMathSync(text: string): MathRenderResult | null {
81-
return renderCache.get(text) ?? null;
104+
return cacheGet(text) ?? null;
82105
}
83106

84107
/**

0 commit comments

Comments
 (0)