如何快速实现markdown流式渲染

1、引言

在AI聊天场景中,Markdown内容的流式渲染变得越来越重要。传统的Markdown渲染器在处理流式内容时往往会遇到语法不完整导致的渲染异常问题。Cherry-Markdown作为一款功能强大的Markdown编辑器,专门针对流式渲染场景进行了深度优化,提供了稳定、高效的流式渲染能力。

2、流式渲染遇到的问题

上图是一个传统的Markdown流式渲染输出的效果,可见在传统的Markdown流式渲染中,开发者会遇到以下问题:

2.1、语法不完整导致的渲染异常

当Markdown内容以字符为单位逐步输出时,语法结构往往是不完整的:

  • 加粗/斜体语法**加粗内容 缺少闭合符号
  • 行内/段落代码块 ```javascript 缺少闭合的 ```````````导致会先显示markdown源码再渲染成代码高亮
  • 表格:表格分隔行不完整
  • 公式:数学公式符号不匹配
  • 标题 : 会先显示##符号再渲染成标题
  • 超链接 :会先显示[xxx](xxxx,最后再变成超链接
  • 图片、音视频:会先显示前面的源码,最后再变成图片或音视频
  • 无序列表 :每次换行输出-时都会命中标题语法,先渲染成标题再渲染成无序列表
  • mermaid画图:渲染过程中由于结构不完整,会经常出现报错
  • 脚注:当脚注语法没有输出完全时,角标无法正常渲染

2.2、渲染性能问题

  • 频繁的DOM更新导致页面卡顿
  • 大量重绘和重排影响用户体验
  • 渲染间隔过长导致"视频"变"幻灯片"

2.3、用户体验不佳

  • 不完整的语法结构暴露给用户
  • 缺乏类似打字机的视觉反馈

3、使用Cherry-Markdown进行流式渲染的效果

上图是使用Cherry-Markdown进行流式渲染的效果,当然也可以在官方在线demo 直接进行体验,Cherry-Markdown通过以下特性解决了上述问题:

3.1 语法自动补全

开启流式渲染模式后,Cherry会自动补全以下语法元素:

  • 标题
  • 加粗、斜体
  • 超链接
  • 图片、音视频
  • 行内代码块
  • 段落代码块
  • 行内公式
  • 段落公式
  • 无序列表
  • 表格
  • mermaid画图
  • 脚注

3.2 性能优化

  • 渲染频率提升:渲染频率可达到10ms/次
  • 增量渲染 :只更新变化的部分内容,尽可能的减少dom重绘区域,如下图:
  • 异步渲染处理:支持图表等异步内容的渲染

3.3 用户体验增强

  • 虚拟光标:提供类似打字机的视觉反馈
  • 稳定输出:避免语法不完整导致的渲染异常

4、如何使用

4.1 基础配置

javascript 复制代码
const cherry = new Cherry({
  editor: {
    height: 'auto',
    defaultModel: 'previewOnly', // 纯预览模式适合流式场景
  },
  engine: {
    global: {
      flowSessionContext: true,     // 开启流式渲染
      flowSessionCursor: 'default', // 添加虚拟光标
    },
  },
  previewer: {
    enablePreviewerBubble: false,   // 关闭预览区编辑功能
  },
});

4.2 流式内容更新

javascript 复制代码
// 模拟流式输出
function streamContent(content, cherryInstance) {
  let currentIndex = 0;
  const interval = setInterval(() => {
    if (currentIndex < content.length) {
      const currentText = content.substring(0, currentIndex + 1);
      cherryInstance.setMarkdown(currentText);
      currentIndex++;
      
      // 自动滚动到最新位置
      const previewer = cherryInstance.previewer.getDom();
      previewer.scrollTop = previewer.scrollHeight;
    } else {
      clearInterval(interval);
      // 流式输出完成后清除虚拟光标
      cherryInstance.clearFlowSessionCursor();
    }
  }, 30); // 30ms的更新间隔
}

// 使用示例
const content = `# 欢迎使用Cherry-Markdown流式渲染

这是一个**加粗文字**的示例。

\`\`\`javascript
console.log("Hello, World!");
\`\`\`

| 项目 | 价格 | 数量 |
|------|------|------|
| 计算机 | ¥1600 | 5 |
`;

streamContent(content, cherry);

4.3 高级配置选项

javascript 复制代码
// 完整的高级配置
const advancedConfig = {
  engine: {
    global: {
      flowSessionContext: true,
      flowSessionCursor: '<span class="custom-cursor">|</span>', // 自定义光标
    },
    syntax: {
      image: {
        selfClosing: true,
        // 图片加载时的占位符
        selfClosingRender: (type, alt, src) => {
          return `<img src="loading.gif" alt="${alt}" data-src="${src}">`;
        }
      },
    }
  },
  // 事件监听
  callback: {
    afterAsyncRender: (markdown, html) => {
      console.log('异步渲染完成:', html);
    }
  }
};

5、总结

Cherry-Markdown的流式渲染功能为现代Web应用提供了强大的Markdown内容展示能力。通过语法自动补全、性能优化和用户体验增强,它完美解决了传统流式渲染中的各种问题。

主要优势:

  1. 稳定性:自动补全语法,避免渲染异常
  2. 高性能:10ms级的渲染频率,增量更新dom,支持大量内容流式展示
  3. 易用性:默认支持丰富的markdown语法和流式渲染机制,通过简单的配置即可实现复杂的流式渲染需求
  4. 扩展性 :支持扩展自定义语法url处理事件处理

Cherry-Markdown的流式渲染功能让开发者能够专注于业务逻辑,而无需担心Markdown渲染的细节问题,是构建现代Web应用的理想选择。

相关推荐
Ama_tor1 天前
obsidian进阶の插件系列|Templater从小白到菜鸟
javascript·markdown·插件·obsidian
Elias不吃糖2 天前
Markdown 基础语法学习笔记
笔记·学习·markdown
杨浦老苏4 天前
轻量级自托管笔记与清单利器jotty·page
笔记·docker·markdown·todo·群晖
恃宠而骄的佩奇5 天前
Typora 免费版本(markdown 编辑器) 无需激活,开箱即用!
编辑器·typora·markdown
JaredYe5 天前
纯 Node.js 的 PDF 转 Markdown 方案:支持图片解析的pdf2md库 `node-pdf-to-markdown`
pdf·node.js·markdown·md·pdf2md
江湖人称小鱼哥9 天前
Obsidian Skills 实测报告:哪些能用,哪些是坑
markdown·obsidian·skill·claude code
程序员老刘9 天前
一杯奶茶钱,PicGo + 阿里云 OSS 搭建永久稳定的个人图床
flutter·markdown
課代表14 天前
大语言模型能够理解的11种文件格式
人工智能·语言模型·自然语言处理·llm·markdown·token·模型
chenshiming80217 天前
AI 编程 Vibe coding 尝试,1 天完成多平台 Markdown 编辑/阅读软件开发
ai编程·markdown·vibecoding
信码由缰17 天前
停止编写Excel规格文档:企业级Java开发的Markdown先行方法
java·ai编程·markdown