perf(chat): use incremental lexing during streaming to avoid re-parsing stable content

This commit is contained in:
silentoplayz 2026-06-08 17:41:46 -04:00
parent 0ffc04797f
commit f0dd2018fa

View file

@ -63,6 +63,10 @@
let lastContent = '';
let lastParsedContent = '';
// Incremental lexing state: cache stable prefix tokens during streaming
let cachedStablePrefix = '';
let cachedStableTokens = [];
const parseTokens = () => {
if (content === lastContent) return;
lastContent = content;
@ -71,7 +75,35 @@
if (processed === lastParsedContent) return;
lastParsedContent = processed;
tokens = marked.lexer(processed);
// When done or for short content, do a full lex for correctness
if (done || processed.length < 2000) {
cachedStablePrefix = '';
cachedStableTokens = [];
tokens = marked.lexer(processed);
return;
}
// Incremental lexing: find the last stable boundary (double newline)
// in the PREVIOUS content. Everything before it won't change as
// streaming only appends to the end.
const boundary = processed.lastIndexOf('\n\n');
if (boundary <= 0) {
tokens = marked.lexer(processed);
return;
}
const stablePrefix = processed.slice(0, boundary + 2);
// If the stable prefix changed, re-lex everything
if (stablePrefix !== cachedStablePrefix) {
cachedStablePrefix = stablePrefix;
cachedStableTokens = marked.lexer(stablePrefix);
}
// Only lex the volatile suffix (current paragraph being streamed)
const volatileSuffix = processed.slice(boundary + 2);
const suffixTokens = volatileSuffix ? marked.lexer(volatileSuffix) : [];
tokens = [...cachedStableTokens, ...suffixTokens];
};
const updateHandler = (content) => {