共计 2279 个字符,预计需要花费 6 分钟才能阅读完成。
开篇:ChatGPT UI 开发三大痛点
在构建 ChatGPT 类对话界面时,新手常会遇到几个典型问题:

- 消息延迟渲染 :当 API 响应慢时,界面会出现明显卡顿
- 长对话内存泄漏 :随着对话轮次增加,DOM 节点堆积导致页面崩溃
- 移动端适配 :传统布局在窄屏幕上出现滚动异常
核心实现方案
状态管理:React Hook 状态机
使用 useReducer 管理对话状态是最佳实践,比 useState 更适合处理复杂状态流转:
type Message = {
id: string;
role: 'user' | 'assistant';
content: string;
timestamp: number;
};
type ChatState = {messages: Message[];
isLoading: boolean;
error: string | null;
};
const initialState: ChatState = {messages: [],
isLoading: false,
error: null
};
function chatReducer(state: ChatState, action: any) {switch (action.type) {
case 'SEND_MESSAGE':
return {...state, isLoading: true};
case 'RECEIVE_MESSAGE':
return {
...state,
isLoading: false,
messages: [...state.messages, action.payload]
};
// 其他 action 处理...
}
}
性能优化:虚拟列表技术
当对话超过 50 条时,常规渲染方式内存占用会飙升:
| 实现方式 | 100 条消息内存占用 | 滚动流畅度 |
|---|---|---|
| 常规列表 | ~45MB | 卡顿 |
| 虚拟列表 | ~12MB | 60fps |
推荐使用 react-window 实现:
import {FixedSizeList} from 'react-window';
const MessageList = ({messages}) => (
<FixedSizeList
height={600}
itemCount={messages.length}
itemSize={120}
width="100%"
>
{({index, style}) => (<div style={style}>
<MessageBubble message={messages[index]} />
</div>
)}
</FixedSizeList>
);
API 层封装:axios 增强版
生产环境必须处理网络异常和重试:
const api = axios.create({
timeout: 10000,
retry: 3, // 自定义重试次数
retryDelay: 1000 // 重试间隔
});
// 请求拦截器
api.interceptors.request.use(config => {if (config.retry) {config.__retryCount = config.__retryCount || 0;}
return config;
});
// 响应拦截器
api.interceptors.response.use(null, error => {
const config = error.config;
if (!config || !config.retry) return Promise.reject(error);
if (config.__retryCount >= config.retry) {return Promise.reject(error);
}
config.__retryCount += 1;
return new Promise(resolve => {setTimeout(() => resolve(api(config)), config.retryDelay);
});
});
生产环境检查清单
1. SSE 连接数限制
浏览器对同一域名有 6 - 8 个并发连接限制,解决方案:
- 使用连接池管理 SSE 实例
- 超过限制时自动排队
- 添加心跳机制保持长连接
2. 敏感词过滤
在服务端和客户端双重校验:
// 前端简单实现
const forbiddenWords = ['暴力', '政治敏感词'];
function validateInput(text) {
return !forbiddenWords.some(word =>
text.toLowerCase().includes(word.toLowerCase())
);
}
3. 对话历史加密
使用 crypto-js 进行本地存储加密:
import CryptoJS from 'crypto-js';
const SECRET_KEY = 'your-secret-key';
function saveChatHistory(messages: Message[]) {
const encrypted = CryptoJS.AES.encrypt(JSON.stringify(messages),
SECRET_KEY
).toString();
localStorage.setItem('chatHistory', encrypted);
}
代码规范要点
- 组件命名采用 PascalCase
- 一个文件只导出一个主要组件
- API 调用必须包含错误边界处理
- TypeScript 类型定义优先
开放思考题
- 打字机效果实现 :可以考虑使用 Web Worker 分块处理文本渲染
- WebSocket vs SSE:
- WebSocket 适合双向高频通信
- SSE 更适合服务端单向推送
- SSE 自动处理断线重连
通过本文介绍的技术方案,开发者可以构建出高性能、稳定的 ChatGPT 类对话界面。建议实际开发时结合业务需求选择最适合的技术组合。
正文完
发表至: 未分类
近三天内
