跳到主要内容

一次前端流式渲染体验优化记录

· 阅读需 2 分钟
一介布衣
全栈开发者 / 技术写作者

补档说明:本文属于「AI 工程落地周记」系列,计划发布时间为 2025-06-25 10:20。当前先保留为草稿,后续补充真实案例、代码片段和复盘细节后再发布。

这次优化很小,但非常值钱。问题出在一个对话页:模型流式返回 token 时,我们最初每收到一段就直接 setState 一次,结果页面在长回答场景里会明显抖动,尤其是移动端更明显。

最初大家直觉上以为这是“模型流太慢”或者“前端机器太差”,但真正看性能面板后才发现,问题不是响应慢,而是我们把过多的小更新直接推给了 React 渲染。

现象

典型表现是:

  • 长回答时滚动条抖动
  • 输入框偶尔失去流畅感
  • 页面并不是卡死,但用户明显感觉“有点顿”

判断

这次问题让我再次确认,流式渲染的关键不是“能不能把 token 打到页面上”,而是“多频更新是否被合并成了用户真正需要感知的节奏”。

如果每个 token 都触发一次视图更新,前端其实是在帮后端把噪音原样放大。

处理

后来我们做了一个很简单的改动:

  • 后端 token 继续实时收
  • 前端按更粗一点的节奏批量刷新视图

这不是改变内容,而是改变显示节奏。代码上类似这样:

let buffer = ''
let framePending = false

function onChunk(chunk: string) {
buffer += chunk
if (framePending) return
framePending = true

requestAnimationFrame(() => {
setDraft(buffer)
framePending = false
})
}

结论

一次前端流式渲染优化最重要的教训是:用户需要的是“稳定更新”,不是“每个 token 都肉眼可见”。把渲染节奏从数据节奏里抽出来,通常比继续盯着模型输出速度更有效。