第一次瞭解到Web Worker的概念還是在騰訊IVWEB團隊的文章中。今天又在《高效能JavaScript》中讀到,於是打算再記錄一下。共同學習!
1. 前言
起初,在瀏覽器的UI執行緒之外無法執行程式碼。但是Web Worker
改變了這種狀況,它引入了一個介面,能使程式碼執行且不佔用瀏覽器UI執行緒的時間。作為HTML5最初的一部分,Web Worker
已經被分離出去成為獨立的規範。
2. Worker
簡介
每個新的Worker都在自己的執行緒中執行程式碼。這意味著Worker執行程式碼不進不會影響瀏覽器UI,也不會影響其他Worker
執行的程式碼。
2.1 Worker
需要注意什麼?
-
Web Worker
沒有繫結UI執行緒,這也意味著它們不能訪問瀏覽器的許多資源。JavaScript和UI共享同一程式的部分原因是它們之間互相訪問頻繁,因此這些任務失控對使用者體驗會是一個災難。 -
Web Worker
從外部執行緒種修改DOM會導致使用者介面出現錯誤,但是每個Worker
都有自己的全域性執行環境,其功能只是JavaScript特性的一個子集。
2.2 Worker
執行環境組成:
-
一個
navigator
物件,只包括四個屬性:appName
、appVersion
、userAgent
和platform
。 -
一個
location
物件(與window.location相同,不過所有屬性都是隻讀的)。 -
一個self物件,指向全域性
Worker
。 -
一個
importScripts()
方法,用來載入Worker
所用到的外部JavaScript檔案。 -
所有的
ECMAScript
物件,諸如:Object、Array、Date等。 -
XMLHttpRequest
構造器。 -
setTimeout()
和setInterval()
方法。 -
一個
close()
方法,它能立刻停止Worker
執行。
由於
Web Worker
有著不同的全域性執行環境,因此你無法從JavaScript程式碼中建立它。事實上,你需要建立一個完全獨立的JavaScript檔案,其中包含了需要在Worker
中執行的程式碼。要建立Worker
執行緒,必須傳入這個JavaScript檔案的URL,例如:let worker = new Worker('workerCode.js');
*此程式碼一旦執行,將為這個檔案建立一個新的執行緒和一個新的
Worker
執行環境。該檔案會被非同步下載,直到檔案下載並執行完成後才會啟動此Worker
。
3. 與Worker
通訊
網頁程式碼可以通過postMessage()
方法給Worker
傳遞資料,它接收一個引數,即需要傳遞給Worker
的資料。此外,Worker
還有一個用來接收資訊的onmessage
時間處理器。例如:
let worker = new Worker('workerCode.js');
woeker.onmessage = function (event) {
alert(event.data);
}
worker.postMessage('Li');
複製程式碼
Worker
通過出發message
事件來接收資料。定義onmessage
事件處理器後,該事件物件就具有一個data
屬性用於存放傳入的資料。Worker
可通過它自己的postMessage()
方法把資訊回傳給頁面:
// workerCode.js檔案
self.onmessage = function (event) {
self.postMessage(event.data + 'is a student.');
}
複製程式碼
*最終的字串在
Worker
的onmessage
事件處理器中構造完成,訊息系統是網頁和Worker
通訊的唯一途徑。
4. Worker
載入外部檔案
Worker
通過importScripts()
方法載入外部JavaScript檔案,該方法接收一個或多個JavaScript檔案URL作為引數。importScripts()
的呼叫過程是阻塞式的,直到所有檔案載入並執行完成之後,指令碼才會繼續執行。由於Worker
在UI執行緒之外執行,所以這種阻塞並不會影響UI相應。例如:
// workerCode.js檔案
importScripts('importFile1.js', 'importFile2.js');
self.onmessage = function (event) {
self.postMessage('Hello' + event.data + '!');
}
複製程式碼
這段程式碼第一行中引入了兩個JavaScript檔案,它們將在Worker
執行緒的上下文中用到。
5. Worker
實際應用
Worker
適用於那些處理純資料,或者與瀏覽器UI無關的長時間執行指令碼。比如:
- 編碼/解碼大字串。
- 複雜數學運算(包括影像或視訊處理)。
- 大陣列排序。
任何超過100ms的處理過程,都應當考慮Worker
方案是不是比基於定時器方案更為合適。比如:
解析一個很大的JSON字串。假設資料量足夠大,至少需要500ms才能完成解析。很明顯時間太長了,超出了客戶端允許JavaScript執行的時間,因為它會干擾使用者體驗。而此任務難以分解成若干個使用定時器的小任務,因此
Worker
成為最理想的解決方案。當然
Web Worker
肯定還有更多其它用處,發揮它更強的作用。
如果有什麼錯誤請各位指出,感謝!