perf(editor): reduce long-document decoration work and fix fold navigation

This commit is contained in:
2026-09-06 14:30:56 +08:00
parent 750e17212e
commit 874e916106
23 changed files with 9398 additions and 54 deletions
+24 -1
View File
@@ -81,13 +81,36 @@ async function loadCodeLanguage(requestedLanguage: string) {
return { shiki, language }
}
// Bounded LRU of dual-theme HTML. Large one-off blocks never remain in the cache.
const highlightedBlocks = new Map<string, string>()
let highlightedCharacters = 0
const highlightBudget = 1_000_000
export async function highlightCode(source: string, requestedLanguage = 'text'): Promise<string> {
const key = JSON.stringify([requestedLanguage.toLowerCase(), source])
const cached = highlightedBlocks.get(key)
if (cached !== undefined) {
highlightedBlocks.delete(key); highlightedBlocks.set(key, cached)
return cached
}
const { shiki, language } = await loadCodeLanguage(requestedLanguage)
return shiki.codeToHtml(source, {
const html = shiki.codeToHtml(source, {
lang: language,
themes: { light: 'github-light', dark: 'github-dark' },
defaultColor: false,
})
const cost = key.length + html.length
if (cost <= highlightBudget / 4) {
// A concurrent caller may already have filled the same entry.
const previous = highlightedBlocks.get(key)
if (previous !== undefined) { highlightedCharacters -= key.length + previous.length; highlightedBlocks.delete(key) }
while (highlightedBlocks.size && (highlightedBlocks.size >= 64 || highlightedCharacters + cost > highlightBudget)) {
const oldest = highlightedBlocks.keys().next().value!
highlightedCharacters -= oldest.length + highlightedBlocks.get(oldest)!.length
highlightedBlocks.delete(oldest)
}
highlightedBlocks.set(key, html); highlightedCharacters += cost
}
return html
}
/** Share the initialized grammar/theme registry with editable code blocks. */