去年在做智能客服项目时,第一次完整实现了前后端协同的AI流式数据传输方案。当用户输入问题后,服务端通过大语言模型实时生成回答,前端需要像真人对话一样逐字显示内容。这种"打字机效果"看似简单,实际涉及网络协议、数据解析、渲染优化等多个技术点的协同。
传统接口交互是"请求-等待-完整响应"模式,而流式传输则是"请求-持续接收-渐进渲染"的过程。这种模式对H5端提出了三个特殊要求:
我们对比了三种实现方案:
最终选择方案:
mermaid复制graph TD
A[用户提问] --> B[HTTP/1.1]
B --> C{是否支持SSE}
C -->|是| D[SSE连接]
C -->|否| E[WebSocket降级]
D/E --> F[数据分片处理]
采用EventSource API作为基础方案,关键代码结构:
javascript复制const eventSource = new EventSource('/api/chat-stream');
eventSource.onmessage = (event) => {
const data = JSON.parse(event.data);
// 处理分片数据
updateChatUI(data.content, data.done);
};
// 错误处理必须包含
eventSource.onerror = () => {
eventSource.close();
fallbackToXHR();
};
流式传输可能遇到以下异常情况:
我们的解决策略:
核心校验逻辑:
javascript复制let buffer = '';
let lastSeq = 0;
function processChunk(chunk) {
if (chunk.seq !== lastSeq + 1) {
requestMissingChunk(lastSeq);
return;
}
buffer += chunk.content;
lastSeq = chunk.seq;
if (chunk.done) {
commitMessage(buffer);
buffer = '';
}
}
实测发现,直接频繁操作DOM会导致移动端卡顿。优化方案:
性能对比数据:
| 优化方案 | 平均FPS | 内存占用 |
|---|---|---|
| 原始方案 | 32 | 210MB |
| 节流方案 | 58 | 150MB |
| 虚拟DOM | 60+ | 120MB |
针对不支持EventSource的浏览器(如IE),我们采用以下降级策略:
javascript复制function initStream() {
if (typeof EventSource !== 'undefined') {
return setupSSE();
} else if (typeof WebSocket !== 'undefined') {
return setupWebSocket();
} else {
return fallbackToLongPolling();
}
}
在iOS Safari上发现两个典型问题:
对应解决方案:
推荐使用以下工具组合:
调试代码示例:
javascript复制// 在关键节点添加标记
window.performance.mark('chunk_received');
// 计算处理耗时
window.performance.measure(
'process_time',
'chunk_received',
'render_complete'
);
我们搭建的监控维度包括:
监控看板示例指标:
流式传输需要特别注意:
安全处理代码:
javascript复制// 内容安全处理
function sanitize(content) {
const div = document.createElement('div');
div.textContent = content;
return div.innerHTML;
}
// 超时控制
const timeout = setTimeout(() => {
eventSource.close();
showTimeoutMessage();
}, 30000);
经过多个项目验证,我们提炼出以下最佳实践:
典型错误示例:
javascript复制// 错误:直接拼接未转义内容
function updateUI(text) {
chatDiv.innerHTML += text; // XSS风险!
}
// 正确做法
function safeUpdate(text) {
const node = document.createTextNode(text);
chatDiv.appendChild(node);
scrollToBottom();
}
在最新项目中,我们还实现了以下增强功能:
这种方案目前稳定支持日均50万+次对话请求,平均延迟控制在1.2秒以内。对于更复杂的场景,可以考虑结合WebTransport等新协议进行升级。