????? 個(gè)人主頁(yè):《愛蹦跶的大A阿》
??當(dāng)前正在更新專欄:《VUE》?、《JavaScript保姆級(jí)教程》、《krpano》
??
?
? 前言
????????Web Worker可以將耗時(shí)任務(wù)放到后臺(tái)執(zhí)行,避免阻塞UI。本文將詳細(xì)介紹Web Worker的用法,讓你可以提升web應(yīng)用性能。
通過(guò)本文你將學(xué)習(xí):
- Web Worker的工作原理
- 不同類型worker的區(qū)別
- worker的創(chuàng)建和通信用法
- worker間的數(shù)據(jù)傳遞方法
- worker的調(diào)試技巧
- worker可以提升應(yīng)用性能的場(chǎng)景
- 彌補(bǔ)worker在老瀏覽器不兼容的方法
準(zhǔn)備讓W(xué)eb Worker成為你的網(wǎng)頁(yè)優(yōu)化利器了嗎?讓我們開始吧!
?
第一節(jié):Web Worker簡(jiǎn)介
Web Worker可以將JS代碼運(yùn)行在后臺(tái)線程,實(shí)現(xiàn)多線程:
- 不阻塞主UI線程,提升互動(dòng)性
- 與主線程同時(shí)運(yùn)行,實(shí)現(xiàn)并行
- 通過(guò)消息傳遞與主線程通信
DEDICATED WORKER:專屬于一個(gè)頁(yè)面 SHARED WORKER:可被多個(gè)頁(yè)面共享
第二節(jié):創(chuàng)建Worker
創(chuàng)建一個(gè)Dedicated Worker的基本步驟是:
- 主線程中用new Worker()實(shí)例化一個(gè)Worker對(duì)象,并傳入腳本的路徑
- 在指定的js腳本中使用self對(duì)象對(duì)worker進(jìn)行編程
- self對(duì)象表示worker的全局作用域,可以添加事件監(jiān)聽器
- 常見的事件有onmessage、onerror等
一個(gè)典型的示例:
// 主線程
const worker = new Worker('work.js');
worker.postMessage('start');
// work.js
self.addEventListener('message', e => {
console.log('worker recv:', e.data);
self.postMessage('hello from worker');
});
Worker線程中不能直接訪問DOM,但可以通過(guò)postMessage()與主線程通信。
創(chuàng)建一個(gè)Shared Worker步驟類似,只是用SharedWorker實(shí)例,并可以指定worker的名稱。
Shared Worker可以被多個(gè)窗口訪問,從而共享同一個(gè)邏輯。
Dedicated Worker專屬于一個(gè)頁(yè)面文檔。根據(jù)實(shí)際需求選擇合適的Worker類型。
創(chuàng)建shared worker:
// 主線程
const worker = new SharedWorker('work.js');
// work.js
self.addEventListener('connect', (e) => {
// 收到連接
});
第三節(jié):worker間通信
主線程 -> worker:
worker.postMessage('hello');
worker -> 主線程:
self.postMessage('hi from worker');
?
- 主線程到worker的通信
主線程使用worker對(duì)象的postMessage()方法向worker發(fā)送消息:
// 主線程
worker.postMessage('start');
?postMessage()可以發(fā)送各種數(shù)據(jù)類型,包括原始類型、對(duì)象、數(shù)組等。
- worker到主線程的通信
worker中使用self.postMessage()發(fā)送:
// worker內(nèi)
self.postMessage('message from worker');
?self代表worker的全局作用域。
- 接收消息
主線程通過(guò)worker.onmessage監(jiān)聽消息:
// 主線程
worker.onmessage = function(e) {
console.log(e.data);
}
worker中通過(guò)self.onmessage監(jiān)聽:
// worker內(nèi)
self.onmessage = function(e) {
console.log(e.data);
}
e.data是消息內(nèi)容。
- 傳遞數(shù)據(jù)注意事項(xiàng)
- 對(duì)象會(huì)串行化,記得調(diào)用JSON.parse()
- 傳遞函數(shù)需要把函數(shù)字符串化
這些是worker間通信的主要方式,可以傳遞不同類型的數(shù)據(jù),充分利用多線程帶來(lái)的好處。
第五節(jié):Worker中的異步請(qǐng)求
Worker線程可以發(fā)出AJAX請(qǐng)求,使用與主線程相同的XMLHttpRequest對(duì)象:
// Worker內(nèi)
const xhr = new XMLHttpRequest();
xhr.open('GET', '/data');
xhr.onload = () => {
self.postMessage(xhr.response);
}
xhr.send();
這樣可以在Worker中完成異步數(shù)據(jù)加載,不影響主UI線程。
第六節(jié):調(diào)試Worker
主線程可以通過(guò)inspect()調(diào)試運(yùn)行中的Worker:
const worker = new Worker();
worker.inspect();
?
這會(huì)打開DevTools來(lái)調(diào)試worker線程。
也可以將console日志發(fā)送到主線程:
// Worker內(nèi)
self.postMessage(console.log.apply(console, arguments));
第七節(jié):使用場(chǎng)景
Worker常用于:
- 超大數(shù)據(jù)排序、搜索、處理
- 數(shù)據(jù)轉(zhuǎn)換與編譯,如Json、Excel
- 高延遲任務(wù)或高計(jì)算工作,如機(jī)器學(xué)習(xí)
第八節(jié):兼容性和代替方案
低版本瀏覽器可能不支持Worker,可以使用polyfill或只在新瀏覽器使用。
也可以使用setTimeout模擬后臺(tái)線程。
? 結(jié)語(yǔ)? ? ?
????????在這篇文章中,我們?nèi)娼榻B了Web Worker的用法 - 它可以將JavaScript代碼運(yùn)行在后臺(tái)線程,實(shí)現(xiàn)多線程計(jì)算。
????????首先,我們看到Web Worker的優(yōu)點(diǎn),它不會(huì)阻塞主UI線程,可以實(shí)現(xiàn)并行執(zhí)行任務(wù)。然后,我們介紹了Dedicated Worker和Shared Worker的區(qū)別,以及創(chuàng)建和終止Worker的方法。
????????接下來(lái),我們重點(diǎn)講解了Worker之間的消息通信機(jī)制,這是利用多線程的關(guān)鍵。我們也討論了Worker中發(fā)起異步請(qǐng)求和調(diào)試技巧。
????????最后,給出了Web Worker的實(shí)際應(yīng)用場(chǎng)景,以及需要注意的兼容性問題。
????????我盡量用通俗的語(yǔ)言和示例給出了全面的講解,希望這篇文章可以幫助大家正確使用Web Worker來(lái)優(yōu)化web應(yīng)用性能。如果還有任何問題,歡迎在評(píng)論交流!文章來(lái)源:http://www.zghlxwxcb.cn/news/detail-802822.html
?文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-802822.html
到了這里,關(guān)于JavaScript Web Worker用法指南的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!