修复: AR-1 流式 Markdown 全量重解析掉帧
renderMd 加 isStreaming 参数:流式态(streaming 中 currentText)纯文本(escapeHtml+<br>)不 parse,避免每 delta 全量 marked.parse+DOMPurify.sanitize 致主线程阻塞掉帧;不缓存流式文本(每 delta 变,污染缓存);完成后再走 markdown 一次 parse 来源 aichat审查报告 第一章 H1 P0;vue-tsc 0 err
This commit is contained in:
@@ -197,7 +197,7 @@
|
||||
class="ai-msg-bubble ai-msg-bubble--ai ai-md"
|
||||
:class="{ 'ai-msg-bubble--error': msg.isError }"
|
||||
>
|
||||
<div v-html="renderMd(isLastAi(msg) && store.state.currentText ? store.state.currentText : msg.content)"></div>
|
||||
<div v-html="renderMd(isLastAi(msg) && store.state.currentText ? store.state.currentText : msg.content, isLastAi(msg) && store.state.streaming)"></div>
|
||||
<span v-if="isLastAi(msg) && isViewingGenerating" class="ai-cursor"></span>
|
||||
</div>
|
||||
<!-- 流式开始但尚无文本时显示光标 -->
|
||||
@@ -344,14 +344,16 @@ function escapeHtml(text: string): string {
|
||||
return text.replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>')
|
||||
}
|
||||
|
||||
function renderMd(text: string): string {
|
||||
function renderMd(text: string, isStreaming = false): string {
|
||||
if (!text) return ''
|
||||
// 流式态纯文本(AR-1):避免每 delta 全量 marked.parse+sanitize 致主线程阻塞掉帧;
|
||||
// 不缓存流式文本(每 delta 变,缓存无收益且污染),仅 escapeHtml + 换行转 <br>;完成后再走 markdown
|
||||
if (isStreaming || !mdReady.value || !_marked || !_purify) {
|
||||
return escapeHtml(text).replace(/\n/g, '<br>')
|
||||
}
|
||||
const cached = _mdCache.get(text)
|
||||
if (cached !== undefined) return cached
|
||||
// 依赖 mdReady 使加载完成后自动重渲染;未就绪时先以纯文本兜底
|
||||
const html = (!mdReady.value || !_marked || !_purify)
|
||||
? escapeHtml(text)
|
||||
: _purify.sanitize(_marked.parse(text) as string)
|
||||
const html = _purify.sanitize(_marked.parse(text) as string)
|
||||
if (_mdCache.size > 200) _mdCache.clear()
|
||||
_mdCache.set(text, html)
|
||||
return html
|
||||
|
||||
Reference in New Issue
Block a user