iT邦幫忙

2023 iThome 鐵人賽

DAY 6
0

昨天提到 postMessage 背後使用了 structuredClone 算法將資料 深複製 (deep copy) 後再進行傳遞,雖然這樣保證了資料的完整性(不同線程間無法修改其他線程的資料),但隨之而來的缺點是當資料量非常大的時候,複製再傳遞的過程會耗費更多時間,今天我們打算實際來測試看看耗費的時間是否會對效能有影響呢?

測試的時間間隔為
主線程發送 postMessage => worker 接收到 message => 主線程接收到 message
程式碼大致如下:

const sendMessage = async (data) => {
  return new Promise((resolve) => {
    worker.postMessage(data);
    worker.onmessage = (e) => {
      resolve(e.data);
    };
  });
};

const start = performance.now();
await sendMessage(data);
const end = performance.now();
const time = end - start;
console.log(`傳遞花費時間:`, `${(time)} ms`);

然後產生要拿來傳送的資料,這裡拿處理 3d 渲染時最常使用到的資料型態 ArrayBuffer,產生的檔案大小從 1KB 到 1GB,使用以下的函式創建:

function generateRandomArray(size) {
  const t1 = performance.now();
  // value 單位是 Bytes (ex. 1KB 的 value = 1024)
  const data = new Uint8Array(new ArrayBuffer(value)).map((_, i) => i);
  const t2 = performance.now();
  console.log(`創建 Array 經過時間:`, `${t2 - t1} ms`);
  return data;
}

測試結果

https://ithelp.ithome.com.tw/upload/images/20230920/20162687QcKQ1arQmu.png
測試環境:Macbook M2,Chrome 116

https://ithelp.ithome.com.tw/upload/images/20230920/20162687IbKlsis3gr.png
測試環境:Macbook M2,Safari 16.4

在我的電腦上跑的時間如上面兩張圖,不知道是不是因為我的 Chrome 開很多分頁的關係,看起來 Chrome 比 Safari 還要更慢。

至於效能上來說如果要符合 RAIL 性能規範 的建議,在 50ms 以內回應使用者的操作,根據以上結果在約略 20 MB 大小以下的矩陣資料傳遞,使用者不會感受到明顯的卡頓,但如果是在硬體不夠強的手機上,能夠處理資料的上限肯定會更少。

這裡提供 Demo,有興趣的話可以試試在不同的裝置上跑分的結果。

最後想分享的這篇文章 - Is postMessage slow? ,作者根據不同的物件分為廣度、深度等層面進行詳細的測試,包含了各個瀏覽器及電腦、手機跑出來的結果,讓我收穫了很多相關知識,建議大家有興趣的話可以閱讀看看。


上一篇
使用 structuredClone 將數據複製到 Web worker
下一篇
可轉移的物件 - Transferable objects
系列文
網頁的另一個大腦:從基礎到進階掌握 Web Worker 技術30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言