前一陣子開發的專案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實現子元件傳資料給父元件 子元...