Transferable objects
Transferable objects are objects that own resources that can betransferred from one context to another, ensuring that the resources are only available in one context at a time.Following a transfer, the original object is no longer usable; it no longer points to the transferred resource, and any attempt to read or write the object will throw an exception.
Transferable objects are commonly used to share resources that can only be safely exposed to a single JavaScript thread at a time.For example, anArrayBuffer is a transferable object that owns a block of memory.When such a buffer is transferred between threads, the associated memory resource is detached from the original buffer and attached to the buffer object created in the new thread.The buffer object in the original thread is no longer usable because it no longer owns a memory resource.
Transferring may also be used when creating deep copies of objects withstructuredClone().Following the cloning operation, the transferred resources are moved rather than copied to the cloned object.
For bothpostMessage() andstructuredClone(), transferred resources have to be attached to the data object, otherwise they would not be available on the receiving end, because the transferable array only indicates how certain resources should be sent, but does not actually send them (although they would always be detached).
The mechanism used to transfer an object's resources depends on the object.For example, when anArrayBuffer is transferred between threads, the memory resource that it points to isliterally moved between contexts in a fast and efficient zero-copy operation.Other objects may be transferred by copying the associated resource and then deleting it from the old context.
Not all objects are transferable.A list of transferable objects isprovided below.
In this article
Transferring objects between threads
The code below demonstrates how transferring works when sending a message from a main thread to aweb worker thread.TheUint8Array is copied (duplicated) in the worker while its buffer is transferred.After transfer any attempt to read or writeuInt8Array from the main thread will throw, but you can still check thebyteLength to confirm it is now zero.
// Create an 8MB "file" and fill it. 8MB = 1024 * 1024 * 8 Bconst uInt8Array = new Uint8Array(1024 * 1024 * 8).map((v, i) => i);console.log(uInt8Array.byteLength); // 8388608// Transfer the underlying buffer to a workerworker.postMessage(uInt8Array, [uInt8Array.buffer]);console.log(uInt8Array.byteLength); // 0Note:Typed arrays likeInt32Array andUint8Array, areserializable, but not transferable.However their underlying buffer is anArrayBuffer, which is a transferable object.We could have sentuInt8Array.buffer in the data parameter, but notuInt8Array in the transfer array.
Transferring during a cloning operation
The code below shows astructuredClone() operation where the underlying buffer is copied from the original object to the clone.
const original = new Uint8Array(1024);const clone = structuredClone(original);console.log(original.byteLength); // 1024console.log(clone.byteLength); // 1024original[0] = 1;console.log(clone[0]); // 0// Transferring the Uint8Array would throw an exception as it is not a transferable object// const transferred = structuredClone(original, {transfer: [original]});// We can transfer Uint8Array.buffer.const transferred = structuredClone(original, { transfer: [original.buffer] });console.log(transferred.byteLength); // 1024console.log(transferred[0]); // 1// After transferring Uint8Array.buffer cannot be used.console.log(original.byteLength); // 0Supported objects
Interfaces that can be transferred should include this information in their introduction.
Some of the items that various specifications indicate can betransferred are listed below (this list may not be exhaustive!):
ArrayBufferAudioDataImageBitmapMediaSourceHandleMediaStreamTrackMessagePortMIDIAccessOffscreenCanvasReadableStreamRTCDataChannelTransformStreamVideoFrameWebTransportReceiveStreamWebTransportSendStreamWritableStream
Note:Transferable objects are marked up inWeb IDL files with the attribute[Transferable].Browser support may be indicated in the respective object's compatibility information by thetransferable subfeature (seeRTCDataChannel for an example).