>_ DevTrendszh

语言

首页

语言

板块

前端 后端 移动端 DevOps AI / ML 游戏开发 区块链 嵌入式 安全
Vue

如何在渲染神经网络流式 Markdown 时避免闪烁和卡顿

当你第一次将语言模型的流式输出连接到前端时,常规的 Markdown 渲染器几乎会立即让页面变成噩梦。标准库如 6 或 7 是为已准备好的静态文档设计的。如果通过 SSE 或 WebSocket 向它们输入原始令牌流,它们会在每个数据块到达时重新解析整个文本,重新绘制 DOM 树,并破坏滚动行为。

此时,界面开始出现明显的闪烁。语法高亮闪烁,未完成的代码块会破坏下面的标记,未闭合的公式会陷入无限加载状态。markstream-vue 仓库正是为了解决这个令人沮丧的问题。

Star History Chart

库的核心原理

该项目最初是 Vue 3 的专用组件,但随着时间推移,作者将架构拆分为核心 8 和针对不同框架的适配器。目前已有适用于 Vue 3、Nuxt、React、Next.js、Svelte 5、Angular 甚至遗留 Vue 2 的现成包。

渲染器的主要任务是保持 DOM 在频繁的文本微更新期间稳定。库会增量解析流,理解未闭合标签的中间状态,只更新更改的节点,让页面的其余部分保持不变。

工作模式和负载管理

库有两种根本不同的渲染方法,可以通过 9 prop 进行切换。

10 模式专为 AI 聊天设计。在该模式下,渲染器将传入的令牌分组为小批次,并以流畅的打字效果输出。同时,不透明度动画被禁用,这样界面不会因每个新词而抖动。

如果你需要显示生成的超长文章或文档,最好通过 11 启用虚拟化。渲染器在活动 DOM 树中保持固定数量的元素窗口(默认约 220 个节点)。这使浏览器内存消耗保持稳定,并防止滚动长对话时出现卡顿。

12

13 prop 在处理流时至关重要。当 13 为 true 时,解析器会从容地容忍中途被截断的语法结构。一旦完成信号到达,渲染器会清除流式缓存并将标记呈现为最终形式。

处理复杂块

常规解析器在 Mermaid 图表或 KaTeX 公式的语法尚未完全写入时会遇到问题。在 markstream 中,这个细节被考虑到了最细微之处。

Mermaid 图表和公式

14 和 15 等重量级依赖项不包含在主包中。你将它们作为 peer 依赖项安装,并通过调用函数来激活它们:

1

Mermaid 图表是渐进式解析的。如果图表仍在被模型写入,渲染器会显示一个整洁的占位符,而不是控制台中的语法错误。对于 KaTeX,你可以通过 CDN 将公式解析卸载到单独的 Web Worker,这样繁重的数学表达式根本不会阻塞主界面线程。

代码块和 diff

在 2.0 版本中,开发者放弃了重量级的 Monaco 编辑器,转而集成 16。现在你可以在流中直接显示交互式文件 diff,在浅色和深色主题之间切换,并配置块高度。

2

在 Markdown 中使用自定义 Vue 组件

有时模型会输出非标准标签,例如用于推理链的 17 或用于调用按钮和小组件的自定义简码。你可以拦截这些并用完整的 Vue 组件替换它们:

3

在模板中,你只需要指定相同的标识符:

4

服务端渲染和状态传递

如果你正在使用 Nuxt 或 Next.js 构建应用,你不必在客户端从头开始运行解析器。文档可以在服务端解析为类型化节点结构:

5

客户端组件通过 18 prop 接收现成的节点,提供快速水合而不会出现布局不匹配。如果你需要在初始页面加载后继续流式传输,客户端只需拾取缓冲区并继续解析新的部分。

实际场景

该库同时覆盖了多个常见的前端开发任务:

  • 与大语言模型的对话界面,消除闪烁和屏幕抖动非常重要。
  • 代码审查和补丁生成系统,在生成过程中直接显示 diff。
  • 知识库和变更日志面板,具有动态部分加载和交互式组件。
  • 带有公式和复杂图表的技术文档页面。

总结

如果你的项目从本地文件夹显示静态 Markdown 文件,一个成熟的 19 可以处理它而不会带来不必要的复杂性。但如果你正在处理来自 LLM 的实时令牌流,将聊天界面迁移到 Web,或者厌倦了在渲染长响应时与延迟作斗争,这个库绝对值得加入你的依赖项中。

它消除了数十个不明显的流式问题,并节省了大量编写自定义解析器变通方案的时间。快速入门可以查看官方在线 playground 或通过 StackBlitz 部署测试环境。

相关项目