如何利用 PostMessage 配合二进制克隆算法加速跨跨域通信性能的重点在于把前置条件、操作顺序和容易误判的地方分清楚。
PostMessage零拷贝仅通过transferList实现,传ArrayBuffer不填该参数将触发结构化克隆;跨域时旧版Chromium可能静默忽略transferList,需用byteLength为0验证是否转移成功。
PostMessage 本身不支持二进制克隆,所谓“二进制克隆算法”不是标准机制,直接配合使用会失效或退化为序列化传输。
浏览器只允许通过 transferList 参数零拷贝传递 ArrayBuffer、MessagePort 等可转移对象。不填 transferList,哪怕传的是 ArrayBuffer,也会被结构化克隆(即深拷贝+序列化),性能无提升。
postMessage(arrayBuffer, [origin], [arrayBuffer]) —— 第三个参数是 transferList 数组postMessage({data: arrayBuffer}, [origin]) —— 包在普通对象里,无法转移,触发完整克隆ArrayBuffer 就以为“传的是二进制”,实际要看是否真正转移成功跨域 iframe 或 window 间调用 postMessage 时,transferList 仍可传 ArrayBuffer,但部分旧版 Chromium(如 v88 之前)会在跨域场景静默忽略 transferList,回退到结构化克隆。结果是:代码无报错、逻辑看似正常、性能却没提升。
event.data.byteLength 是否为 0(转移后原 buffer 失效,长度变 0);若仍 > 0,说明未转移成功SharedArrayBuffer 在跨域中默认禁用(需 COOP/COEP 头),不能靠它补位Web 标准中不存在名为“二进制克隆”的独立算法。开发者常把 structuredClone(ES2022)误称为“二进制克隆”,但它处理 ArrayBuffer 时仍走拷贝路径,且不支持 transferList。它和 postMessage 是两套机制,不能混用加速。
structuredClone(arrayBuffer) 返回新 ArrayBuffer,内存复制不可避免postMessage 的零拷贝能力只来自 transferList,和 structuredClone 无关structuredClone 再 postMessage + transferList,反而多一次拷贝,更慢真正影响跨域通信性能的,是是否启用 transfer、目标环境是否支持、以及 ArrayBuffer 是否真的脱离主线程独占——这些细节比“用什么算法”重要得多。一旦 transfer 失败,所有优化都归零。