You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Node Websocket 向客户端发送大型数组数据的最优实现方案

WebSocket 大体积对象数组传输优化方案

直接通过JSON.stringify序列化大数组延迟高主要有两个核心原因:一是20万行级别的数据JSON序列化本身CPU开销极高,二是字符串格式的传输冗余度大,相同有效内容的体积远高于二进制格式。以下是可落地的优化方案:

优先方案:二进制序列化 + ArrayBuffer 传输

使用专门的二进制序列化协议替代JSON,同时直接传输二进制数据,序列化速度比JSON快2~5倍,传输体积可降低30%以上,是投入产出比最高的优化方式。这里以轻量高性能的msgpackr库为例:

服务端实现(Node.js)

  1. 安装依赖:
npm install msgpackr
  1. 发送逻辑:
const { pack } = require('msgpackr');
// bigDataArray 为你需要发送的20万行对象数组
const binaryData = pack(bigDataArray);
// Node.js Buffer 属于 Uint8Array 类型,可直接通过WebSocket发送
ws.send(binaryData);

客户端实现

  1. 安装同依赖(浏览器环境可直接引入UMD版本)
  2. 接收逻辑:
import { unpack } from 'msgpackr';
// 指定接收的二进制数据格式为ArrayBuffer
ws.binaryType = 'arraybuffer';
ws.onmessage = (event) => {
  if (event.data instanceof ArrayBuffer) {
    // 解码二进制数据得到原始对象数组
    const originData = unpack(new Uint8Array(event.data));
    // 后续业务逻辑处理
  }
}

注意:不要直接将JSON字符串转为ArrayBuffer传输,这类操作不会降低序列化开销,也不会明显缩小传输体积,无法获得性能收益。

进阶方案:分片传输

如果单包数据体积超过10MB,建议拆分为多个分片发送,避免网络波动导致整包重传:

const binaryData = pack(bigDataArray);
const chunkSize = 1024 * 1024; // 单分片大小设为1MB,可根据实际场景调整
const totalChunks = Math.ceil(binaryData.length / chunkSize);
for (let i = 0; i < totalChunks; i++) {
  const start = i * chunkSize;
  const end = Math.min(start + chunkSize, binaryData.length);
  const chunk = binaryData.slice(start, end);
  // 前两个字节存储总分片数和当前分片序号,方便客户端拼接
  ws.send(Buffer.concat([Buffer.from([totalChunks, i]), chunk]));
}

客户端接收时按序号拼接所有分片后再解码即可。

附加优化:数据压缩

如果你的对象数组重复度很高(比如大量对象的key相同、字段值重复),可以在序列化后增加压缩步骤,重复度高的场景下体积可再降低50%以上:

const zlib = require('zlib');
const binaryData = pack(bigDataArray);
zlib.gzip(binaryData, (err, compressedData) => {
  if (!err) ws.send(compressedData);
});

客户端接收后先做gzip解压,再执行二进制解码即可。

额外建议

如果业务场景允许增量更新,优先调整为增量推送逻辑,仅推送发生变化的部分数据,性能收益远高于全量数据传输优化。

内容的提问来源于stack exchange,提问作者Mr.Online

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.25 22:27:04