原型链不影响 postMessage 性能,结构化克隆仅保留值、忽略原型;性能取决于数据形状(嵌套深度、对象数量、类型复杂度);优化应聚焦数据精简、传输方式及 transfer 使用。

原型链本身不参与跨标签页通信的序列化过程,也不会带来额外损耗。postMessage 的序列化开销来自结构化克隆算法,而该算法完全忽略原型链信息。
结构化克隆只保留“值”,不保留“原型”
当你调用 postMessage(obj, origin) 时,浏览器执行的是结构化克隆(Structured Clone),不是 JSON 序列化,也不是基于原型链的深拷贝:
- 克隆结果是一个**全新对象**,其
__proto__指向Object.prototype(或对应内置构造器的原型,如Date.prototype),与原对象的自定义原型链无关 - 如果你传的是
class Person { ... }的实例,接收方收到的只是一个普通 plain object,没有Person.prototype上的方法,也不满足instanceof Person - 函数、undefined、Symbol、constructor、getter/setter、循环引用等不可克隆项会被直接丢弃,原型链上的这些特性自然也一并消失
真正影响性能的是数据“形状”,不是“原型”
序列化耗时取决于对象的结构特征,而非它的继承关系:
- 深层嵌套的对象或数组:克隆需递归遍历每一层,深度越大,栈开销和时间越长
- 大量小对象组成的集合(如 [{id:1},{id:2},...]):比同等体积的扁平数组更慢,因每个对象都要单独分配、检查可克隆性
- 含 ArrayBuffer 视图(Uint8Array)、Map、Set、Date 等类型:虽支持克隆,但内部处理逻辑更重;若未用
transfer,ArrayBuffer 还会触发完整内存拷贝 - 自定义原型上挂了方法或大字段?只要没被显式赋值到实例自身(即不在
obj.hasOwnProperty(key)中),结构化克隆根本看不到它们
误传“带原型的实例”反而埋下隐患
开发者有时会无意中把组件实例、状态管理器或调试对象传进 postMessage,以为只是“发个对象”。这类对象常有以下问题:
立即学习“Java免费学习笔记(深入)”;
- 闭包捕获了大量上下文变量(如 Vue 组件实例持有
$data、$refs、$watchers),克隆时实际复制的是整个依赖图 - DOM 节点或 Event 对象:不可克隆,postMessage 会静默失败或抛出
DataCloneError - 即便成功克隆,接收方也无法调用原型方法——这不是损耗问题,而是功能断裂
优化方向始终围绕“数据精简”和“传输方式”
别纠结原型链是否被序列化,要聚焦于你实际传了什么、怎么传:
- 发送前做数据净化:用解构、
Object.assign({}, pick(obj, ['id', 'name']))只留必要字段 - 大数据量(如图片像素、日志块)改走 Blob URL 或 IndexedDB,postMessage 只传路径或 key
- 高频消息(如拖拽坐标)加节流,合并为单次 payload,避免每帧都触发克隆
- 需要零拷贝传递二进制数据时,明确使用
transfer参数移交 ArrayBuffer,此时连克隆都跳过


















