Web API - Message Channel學習的過程中看到了 postMessage, 其中有個 Transfer 參數,一直想不通到底是怎麼使用的,並且閱讀了 MDN 也不理解,於是只好帶著問題來問問 AI。
// Workers or MessagePort
target.postMessage(message, [transfer])
// Window or Iframe
targetWindow.postMessage(message, targetOrigin, [transfer])
不管是 worker 或是 window 的 postMessage method 都可以帶一個 transfer 的參數,接下來就來介紹一下。
當 PostMessage 不使用 Transfer 時預設會遞迴地遍歷你傳遞的 message
物件做 Deep Copy 建立副本來給接收方,並且 Deep Copy 支援以下類別:
但是不支援複製 Error Object, Function Object, DOM 節點。
其最終結果會是發送方會有一個原始資料,而接收方會有一個一樣的副本,但是這樣做就有可能會面臨到在 Deep Copy 時遇到了大量資料導致會阻塞發送方的執行緒的問題,如果發送方是主執行緒那就有可能會遇到畫面卡頓。
當使用了 Transfer 參數的時候就可以做到所有權的轉移,可以指定 message 物件中的特定資料不該用複製的而是直接移交所有權,這樣一來此物件的所有權就會交到接收方的執行緒,就不需要建立副本給接收方,但除此之外還有幾點:
(可以透過 codeSandbox 測試)
以 ArrayBuffer 為例
transfer
(複製):postMessage(buffer)
。ArrayBuffer
物件。ArrayBuffer
物件。transfer
(轉移):postMessage(buffer, [buffer])
。ArrayBuffer
物件與其底層原始記憶體塊之間的連結(使其 “neutered”)。ArrayBuffer
物件。引擎將這個新的 ArrayBuffer
物件指向先前那個原始的記憶體塊。ArrayBuffer
物件。