Transferable Objects 是 HTML5 实现零拷贝数据传输的核心机制,通过直接转移 ArrayBuffer、MessagePort、ImageBitmap 等对象所有权,避免序列化与深拷贝开销;使用时需显式传入 transfer 数组,转移后原引用失效,目标端获得内存控制权。

Transferable Objects 是 HTML5 中实现零拷贝数据传输的核心机制,它允许在主线程与 Web Worker 之间(或不同 Worker 之间)**直接转移对象的所有权**,而非复制其底层内存。这避免了大体积数据(如 ArrayBuffer、ImageBitmap、MessagePort 等)的序列化与深拷贝开销,显著提升性能。
哪些对象支持转移权限?
只有特定类型对象可被转移,且必须显式传入 transfer 参数。常见可转移对象包括:
-
ArrayBuffer:最常用,转移后原引用变为
null,内存归属立即移交 - MessagePort:用于跨线程通信通道的移交(如建立 Worker 间双向通信)
- ImageBitmap:图像解码后的位图数据,转移后主线程无法再访问像素
- OffscreenCanvas(部分浏览器支持):可转移其渲染上下文控制权
- AudioData(Web Audio API 实验性支持)
如何正确使用 transfer 参数?
调用 postMessage() 时,将可转移对象放入 transfer 数组,格式为:
worker.postMessage(message, transferList)
立即学习“前端免费学习笔记(深入)”;
例如转移一个 10MB 的 ArrayBuffer:
const buffer = new ArrayBuffer(10 * 1024 * 1024);
const view = new Uint8Array(buffer);
// 填充数据...
worker.postMessage({ data: buffer }, [buffer]); // 关键:传入 [buffer] 表示转移所有权
执行后:
– 主线程中 buffer 仍存在,但 buffer.byteLength === 0,不可读写;
– Worker 收到的 message.data 是同一块内存的 ArrayBuffer 引用,可直接使用。
转移失败的常见原因
转移不是总能成功,需注意以下限制:
- 同一个 ArrayBuffer 不能多次转移(转移后原引用失效,再次传入会抛
DataCloneError) - 不能转移普通对象、TypedArray 视图(如
Uint8Array)、JSON 或 DOM 节点——只能转移其底层ArrayBuffer - 若传递的是视图(如
new Uint8Array(buffer)),需先取view.buffer再转移 - Firefox 和 Safari 对
ImageBitmap转移的支持晚于 Chrome,需检查兼容性
零拷贝 ≠ 无成本
转移本身不复制内存,但仍涉及所有权切换和线程间同步开销。尤其在高频小数据传输场景,频繁转移可能不如共享内存(如 SharedArrayBuffer + Atomics)高效。实际选择应基于数据规模与使用模式:
- 单次大块数据(≥1MB)→ 优先用 Transferable
- 多轮读写共享 → 考虑
SharedArrayBuffer(需启用跨域隔离) - 图像处理流水线 → 结合
ImageBitmap.transferToImageBitmap()与OffscreenCanvas转移


















