Worker线程通信性能瓶颈在于数据格式设计,应使用2层内POJO、原始类型和TypedArray,避免嵌套结构与不可序列化对象,并通过简短字段名、分块传输和上下文标识优化传输效率。

Worker 线程间通信的性能瓶颈,主要不在“怎么发”,而在于“发什么”和“怎么组织”。数据格式设计不合理,会让结构化克隆开销成倍放大,甚至引发内存暴涨或 GC 频繁。优化通信数据格式,本质是让序列化更轻、传输更准、解析更稳。
用扁平对象代替嵌套结构
结构化克隆对深度嵌套对象(如多层嵌套的 map、list、自定义 class 实例)序列化耗时高,且容易因循环引用失败。 建议始终传递 Plain Old JavaScript Objects(POJO),字段层级控制在 2 层以内: - ✅ 推荐:`{ id: 1, name: "task", value: 42, timestamp: 1718982120 }` - ❌ 避免:`{ meta: { user: { profile: { avatar: ... } } }, data: [...] }` 如果业务必须分组,可拆成多个独立消息,或提前 flatten 成键值对数组(如 `[{key: 'a', val: 1}, {key: 'b', val: 2}]`)。优先传原始类型和 TypedArray,避开复杂对象
结构化克隆支持的类型中,以下最高效: - 字符串、数字、布尔、null、undefined(零序列化成本) - `Uint8Array`、`Float32Array`、`ArrayBuffer`(配合 Transferable Objects 可零拷贝) - 简单数组(`[1, 2, 3]`)和对象字面量(`{ x: 1, y: 2 }`)应避免传递:
- Date、RegExp、Map、Set、Function(不可序列化,会静默丢弃或报错)
- 自定义类实例(序列化后变为空对象
{}) - 大型 JSON 字符串(需双重解析:先 parse 再序列化)
约定字段名,减少冗余键名重复传输
每次传输都带完整字段名(如 `{ userId: 123, action: 'update', payload: {...} }`),在高频小消息场景下,字符串键名本身就会占大量体积。 可行做法: - 使用简短、固定字段名(如 `u`、`a`、`p`)并维护一份文档映射表 - 对固定结构的消息,改用定长数组或 ArrayBuffer 手动编码(例如 `[typeId, userId, timestamp, status]`) - 在 Worker 初始化阶段协商 schema,后续只传数值数组,省去键名开销按需切片 + 带上下文标识
大数据不一次性全传,小消息不零散乱发: - 分块传输时,每块附带 `chunkId` 和 `totalChunks`,方便主线程拼接校验 - 多任务并发时,每个消息带上 `requestId`,避免响应错乱或覆盖 - 不同类型任务用 `type` 字段区分(如 `'filter'`、`'render'`、`'encode'`),Worker 内部用 switch 分流,比 if-else 判断更清晰高效不复杂但容易忽略

















