web worker 的傳值方式以及耗時對比

2021-09-11 10:04:51 字數 2188 閱讀 2842

前一陣子開發的專案pptx 匯入, 由於自己的**問題,引起了個效能問題,乙個 40p 的 pptx 檔案,轉換成 json 資料, 大概要耗時 60s+ ,雖然後面發現是某個使用頻率非常高的函式內部,用了new function 建構函式造成的 (所以這裡順便提醒一下,如果你很在乎幾毫秒的差距的話,建議謹慎使用哈), 但是在優化的過程中,一度懷疑是效能達到了瓶頸,所以嘗試了使用 web worker 去優化,由於是檔案,一般內容都比較大, 發現 web worker 在傳值這塊占用了大部分的時間,所以想開這篇來詳細聊聊.

關於 web worker 的基本用於以及傳值方式,網上以及有一大堆介紹了,這裡就不贅述了, 這裡我們重點來看一下同乙個檔案用兩種方式來傳值,會有多大的差別,這邊隨意從電腦裡面找了乙個 96mb 的 psd 檔案來測試.

主線程

fetch('./case.psd').then(file => )

.then(blob =>

filereader.readasarraybuffer(blob);

})})

.then(buf =>

})複製**

worker(子)執行緒, 這裡為了避免不必要的因素干擾,worker 執行緒裡面什麼也不做,在收到訊息後,直接 post 乙個訊息回去

self.onmessage = e => 

複製**

這邊我直接用 filereader 的 readasarraybuffer,讀出來是乙個長度為 96,138,230 的字串, 長度大概 0.96 億, 耗時大概 70ms 左右(同乙個臺電腦取 10 次平均值,下同)

我們稍微改一下上面主線程的**,改用轉移資料的方式

- worker.postmessage(buf);

+ worker.postmessage(buf, [buf]);

複製**

同樣的資料, 耗時大概 17ms 左右,這 17ms 好像是個固定值,我嘗試換了個 800mb+ 的檔案和乙個裡面啥都沒有的空文字檔案, 大概都是這個時間.

fetch('./case.psd').then(file => )

.then(blob =>

filereader.readastext(blob);

})})

.then(str =>

})複製**

這裡我們改用 filereader 的 readastext,讀出來是乙個長度為 95,855,954 的字串,長度大概 0.95 億, 耗時大概 118ms 左右, 同樣我換了上面那個裡面啥都沒有的空文字檔案,耗時也是 17ms 左右.

那我們試試用 readasdataurl 看看讀出來的資料要多久

fetch('./case.psd').then(file => )

.then(blob =>

filereader.readasdataurl(blob);

})})

.then(str =>

})複製**

讀出來是乙個長度為 128,184,345 的字串,長度大概 1,28 億, 耗時大概 85ms 左右(雖然字串長度更長,但是耗時卻更短)

以上耗時,均為主線成向 worker 執行緒單向傳遞資料的耗時.

轉移資料幾乎是零開銷(因為和傳遞空字串的耗時是差不多的).

值傳遞的話,不同的資料型別,耗時也有差別,arraybuffer < base64 < 普通字串.

postmessage 傳遞訊息,除了傳送資料的耗時外,還有其他開銷(就是上面的 17ms). 當然每台電腦效能不一樣,耗時也是不一樣的,不過按比例來看,這個佔比還挺大的.

關於轉移的缺點, 網上也是有很多的, 這裡也就不囉嗦了, 總結一句就是資料無法同時在2個執行緒上使用.

另外個人覺得如果是普通的資料,為了轉移而去轉換成transferable objects的話, 大部分情況下是划不來的, 因為你需要在花在編碼解碼上的時間,會比直接傳遞花的時間多.

另外, 如果你是要用子執行緒處理的話,imagebitmap格式 配合最近新鮮出爐的offscreencanvas也許是不錯的選擇.前提是你不需要考慮相容性問題.

web worker 的傳值方式以及耗時對比

前一陣子開發的專案pptx 匯入,由於自己的 問題,引起了個效能問題,乙個 40p 的 pptx 檔案,轉換成 json 資料,大概要耗時 60s 雖然後面發現是某個使用頻率非常高的函式內部,用了new function 建構函式造成的 所以這裡順便提醒一下,如果你很在乎幾毫秒的差距的話,建議謹慎使...

元件傳值的方式

父傳子 傳遞 當子元件在父元件中當做標籤使用的時候,給當前子元件繫結乙個自定義屬性,值為需要傳遞的資料 接收 在子元件內部通過props屬性來進行接收。props接收的方式有2種一種為陣列 另一種為物件 1 陣列接收 props 自定義屬性 2 物件接收 props type 限制外部資料的型別 d...

Vue傳值方式

1.provide和inject實現祖先與後代元件傳值 祖先元件 export default provide 後代元件 export default 2.props實現父向子傳值 父元件 zhnagsan age 2 子元件 export default 3.emit實現子元件傳資料給父元件 子元...