HTMLPAGE Logo

流式生成技术架构

作者:HTMLPAGE
发布日期:2025-11-27
AI 技术

深入解析基于 SSE 的增量式渲染与实时流式生成引擎

HTMLPAGE 的流式生成技术(Streaming Generation)彻底改变了传统的"请求-等待-响应"模式。通过 Server-Sent Events (SSE) 和增量渲染引擎,我们实现了毫秒级的首字响应(TTFT),让用户能够实时目睹 AI 的思考与构建过程,就像看着一位设计师在眼前现场作画。

🌊 流式传输架构

SSE vs WebSocket

在技术选型上,我们选择了 SSE (Server-Sent Events) 作为主要的流式传输协议,而非 WebSocket。

特性SSE (Server-Sent Events)WebSocket为什么选择 SSE?
通讯方向单向 (Server -> Client)双向生成过程主要是服务器推送,单向足够
协议复杂度简单 (基于 HTTP)复杂 (自定义协议)SSE 原生支持 HTTP/2 多路复用和防火墙穿透
自动重连浏览器原生支持需手动实现SSE 内置重连机制,更稳定
数据格式文本流 (Text Stream)二进制/文本适合传输 JSON Patch 或 Markdown 片段

流式管道设计

我们的流式生成管道由三个核心阶段组成:

  1. Token 生成层:LLM 逐个 Token 输出。
  2. 结构化解析层:将 Token 流实时组装成结构化的 JSON Patch 或 HTML 片段。
  3. 增量传输层:通过 SSE 通道将差异数据推送到前端。
sequenceDiagram participant Client participant Gateway participant StreamEngine participant LLM Client->>Gateway: POST /api/generate (Stream=true) Gateway->>StreamEngine: Init Generation Task StreamEngine->>LLM: Prompt Request loop Token Streaming LLM-->>StreamEngine: Token "<div>" StreamEngine-->>StreamEngine: Buffer & Parse StreamEngine-->>Gateway: SSE Event: { type: "patch", data: "..." } Gateway-->>Client: SSE Event Client-->>Client: Incremental Render end StreamEngine-->>Gateway: SSE Event: { type: "done" } Gateway-->>Client: Close Connection

⚡ 增量渲染引擎

虚拟 DOM 补丁策略

前端接收到流式数据后,并非简单地追加 HTML 字符串,而是通过虚拟 DOM 补丁(Virtual DOM Patching)技术,智能地更新页面结构。

增量更新算法示例

class IncrementalRenderer { constructor(container) { this.vdom = null; this.container = container; } // 处理 SSE 消息 onPatchReceived(patch) { // 1. 应用 JSON Patch 到当前状态 const nextState = applyPatch(this.currentState, patch); // 2. 生成新的虚拟 DOM const nextVdom = renderToVdom(nextState); // 3. 计算最小差异 (Diff) const diff = diffVdom(this.vdom, nextVdom); // 4. 仅更新变动的 DOM 节点 patchDom(this.container, diff); // 5. 更新引用 this.vdom = nextVdom; this.currentState = nextState; } }

渐进式水合 (Progressive Hydration)

为了提升交互性能,我们采用了渐进式水合策略。

  1. 骨架屏 (Skeleton):连接建立瞬间,立即渲染页面骨架。
  2. 静态内容 (Static Content):优先渲染文本、图片占位符等静态资源。
  3. 交互逻辑 (Interactivity):当组件结构渲染完成后,异步加载并激活对应的 JavaScript 逻辑。

🛡️ 容错与状态恢复

智能断点续传

网络波动是流式传输的大敌。我们设计了基于 Last-Event-ID 的断点续传机制。

  • 服务端缓存:服务端会缓存最近 1 分钟的生成流数据。
  • 自动重连:当连接断开时,浏览器会自动发起重连,并带上 Last-Event-ID
  • 无缝恢复:服务端根据 ID 补发丢失的数据包,前端无感知地继续渲染。

乱序处理

虽然 TCP 保证了包序,但在复杂的网络环境下(如 HTTP/3 UDP),应用层仍需处理潜在的数据一致性问题。

  • 序列号校验:每个 SSE 事件都带有递增的 seq_id
  • 缓冲队列:前端维护一个缓冲队列,确保严格按 seq_id 顺序处理事件。

🚀 性能优化策略

背压控制 (Backpressure)

当生成速度超过前端渲染速度时(例如在低端移动设备上),会导致 UI 卡顿。我们实现了应用层的背压控制。

// 前端流控制器 const streamController = new WritableStream({ write(chunk) { // 如果渲染队列过长,暂停读取流 if (renderQueue.length > HIGH_WATER_MARK) { return new Promise(resolve => { eventBus.once('drain', resolve); }); } processChunk(chunk); } });

智能分块 (Smart Chunking)

服务端不会每生成一个字符就发送一次 SSE 事件,而是采用智能分块策略,平衡实时性与网络开销。

  • 语义分块:尽量在完整的单词、HTML 标签或句子结束时发送数据包。
  • 自适应频率:根据网络 RTT 动态调整发送频率(如:50ms - 200ms)。

📊 用户体验设计

视觉平滑处理

为了避免文字逐字跳动带来的视觉疲劳,前端实现了"打字机平滑效果"。

/* CSS 动画平滑过渡 */ .streaming-text-cursor::after { content: '|'; animation: blink 1s step-end infinite; } .new-content-fade-in { animation: fadeIn 0.3s ease-out; }

进度预估

虽然流式生成没有确定的结束时间,但我们通过训练一个轻量级的预测模型,根据 Prompt 复杂度和当前生成速度,实时估算剩余时间,缓解用户等待焦虑。

🔗 相关技术文档


流式生成不仅是技术的革新,更是交互范式的升级。HTMLPAGE 让等待不再枯燥,让创作过程本身成为一种享受。

微信中可直接分享当前页面