fix(client): stabilize syntax highlighting under load

This commit is contained in:
Tianyi Cui
2026-08-09 01:32:17 +08:00
parent 9e724dcad7
commit 317c3bd178
4 changed files with 22 additions and 4 deletions

View File

@@ -19,7 +19,7 @@
*/
import { createHighlighterCoreSync, createCssVariablesTheme } from 'shiki/core'
import { createJavaScriptRegexEngine } from 'shiki/engine/javascript'
import { createJavaScriptRegexEngine, defaultJavaScriptRegexConstructor } from 'shiki/engine/javascript'
import langTs from '@shikijs/langs/typescript'
import langBash from '@shikijs/langs/shellscript'
import langJson from '@shikijs/langs/json'
@@ -140,6 +140,20 @@ const cssVariablesTheme = createCssVariablesTheme({
fontStyle: true,
})
/**
* The client regex engine compiles each TextMate pattern when its scanner is
* created. Shiki otherwise defers patterns longer than 3,000 characters until
* their first match; that compilation counts against Shiki's 500 ms per-line
* budget and can return a partial token stream under host contention. Eager
* compilation leaves the same budget in place for scanning user content.
*/
const regexEngine = createJavaScriptRegexEngine({
forgiving: true,
regexConstructor: pattern => defaultJavaScriptRegexConstructor(pattern, {
lazyCompileLength: Number.POSITIVE_INFINITY,
}),
})
let singleton: HighlighterCore | undefined
/** The synchronous highlighter (one instance per document); pre-warmed below, lazy as the fallback. */
@@ -147,7 +161,7 @@ function highlighter(): HighlighterCore {
singleton ??= createHighlighterCoreSync({
themes: [cssVariablesTheme],
langs: LANGS,
engine: createJavaScriptRegexEngine({ forgiving: true }),
engine: regexEngine,
})
return singleton
}