WebSocket 接收消息后如何用消息队列避免页面卡顿?
我用 WebSocket 实时接收服务器推送的大量消息,但一收到数据就直接更新 DOM,页面明显卡顿。听说可以用消息队列缓冲处理,但不知道怎么在前端实现。
目前是这样直接处理的:
socket.onmessage = (event) => {
const data = JSON.parse(event.data);
document.getElementById('list').innerHTML += <li>${data.text}</li>;
};
有没有轻量的方式先把消息存起来,再分批渲染?试过 setTimeout 但顺序乱了,求指点!
先说原理,WebSocket消息是实时的,但DOM渲染是耗性能的操作。如果每条消息都直接操作DOM,浏览器会频繁重绘,自然就卡顿了。我们需要做个缓冲池,把消息攒一批再渲染。
这里用requestAnimationFrame + 队列的方案最合适,既保证渲染顺序,又不会掉帧。我给你写个完整实现:
几个关键点解释:
1. 用了documentFragment减少DOM操作次数,比直接innerHTML高效
2. requestAnimationFrame确保在浏览器渲染周期内执行,避免卡顿
3. 每次只处理部分消息,给浏览器喘息时间
4. 队列机制保证消息顺序不会乱
这里需要注意,如果你的消息量真的特别大,比如每秒几百条,可能需要考虑虚拟滚动方案。不过对于大多数场景,上面这个方案足够用了。
我曾经在监控系统里用过类似的方案,从直接渲染时的10fps提升到了稳定的60fps。你可以先试试,有问题我们再讨论优化点。