最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

JS中webworker的作用與實操示例詳解

 更新時間:2025年07月26日 08:34:45   作者:搞前端的小王  
WebWorker是HTML5新引入的一種技術(shù),旨在為Web內(nèi)容在后臺運(yùn)行腳本提供一種簡單的方法,這篇文章主要介紹了JS中webworker的作用與實操的相關(guān)資料,文中通過代碼介紹的非常詳細(xì),需要的朋友可以參考下

為什么需要webworker

JavaScript 需要引入 ‌Web Worker‌ 的核心原因源自其‌單線程模型的局限性‌。以下是關(guān)鍵原因及技術(shù)價值分析:

一、突破單線程阻塞瓶頸

1.JS 單線程的本質(zhì)

JavaScript 設(shè)計之初基于單線程模型,主線程需同時處理 ‌UI 渲染、事件響應(yīng)、邏輯計算‌等任務(wù)。若執(zhí)行耗時操作(如大數(shù)據(jù)計算),會導(dǎo)致頁面卡頓甚至無響應(yīng),用戶體驗急劇下降‌。Web 2.Worker 的解決方案

創(chuàng)建獨(dú)立的后臺線程運(yùn)行腳本,將復(fù)雜任務(wù)剝離主線程,避免阻塞關(guān)鍵渲染流程‌

二、釋放多核 CPU 性能潛力

‌1.并行計算能力

Web Worker 允許創(chuàng)建多個子線程,將任務(wù)分片并行處理(如圖像濾鏡、科學(xué)計算),充分利用多核 CPU 硬件資源,顯著提升處理效率‌

2.資源分配優(yōu)化

主線程專注 UI 交互與渲染,Worker 線程處理計算密集型任務(wù),實現(xiàn)計算資源合理分配‌

三、增強(qiáng)應(yīng)用穩(wěn)定性與體驗

1.崩潰隔離機(jī)制

Worker 線程運(yùn)行在獨(dú)立環(huán)境中,即使子線程崩潰或報錯,也不會影響主線程及其他 Worker 的穩(wěn)定性‌

2.流暢的用戶交互保障

例如實時金融圖表渲染場景,主線程僅負(fù)責(zé)接收結(jié)果并渲染,確保用戶操作無延遲‌

webworker的原理

Web Worker 是 JavaScript 實現(xiàn)多線程的核心機(jī)制,其原理涉及底層線程模型、通信機(jī)制和環(huán)境隔離等多個關(guān)鍵技術(shù)點。

核心工作機(jī)制詳解

1. ‌獨(dú)立線程模型‌

  • Web Worker 在‌獨(dú)立操作系統(tǒng)線程‌中運(yùn)行(非主線程)
  • 瀏覽器為每個 Worker 分配:
    • 獨(dú)立內(nèi)存堆棧空間
    • 專屬 JavaScript 執(zhí)行環(huán)境
    • 隔離的全局上下文 (self 代替 window)

2. ‌線程間通信機(jī)制

// 主線程

const worker = new Worker('worker.js');
worker.postMessage(data); // 發(fā)送數(shù)據(jù)
// Worker 線程 (worker.js)
self.onmessage = (e) => {
        const result = process(e.data); self.postMessage(result); // 返回結(jié)果
}

3. ‌事件循環(huán)隔離‌

特性主線程Web Worker
事件循環(huán)UI渲染+JS執(zhí)行純JS執(zhí)行環(huán)境
阻塞影響導(dǎo)致頁面凍結(jié)僅影響自身線程
任務(wù)優(yōu)先級高(UI響應(yīng)優(yōu)先)低(計算任務(wù)優(yōu)先)

4. ‌資源訪問限制‌

Web Worker ‌無法訪問‌:

  • DOM API (documentwindow)
  • 父頁面變量/函數(shù)
  • 部分BOM API (alertlocalStorage)

但‌可以訪問‌:

  • XMLHttpRequest/Fetch
  • setTimeout/setInterval
  • WebSockets
  • IndexedDB

5. ‌線程生命周期管理‌

// 創(chuàng)建Worker
const worker = new Worker('worker.js');
// 終止Worker (立即停止)
worker.terminate();
// Worker內(nèi)部自終止
self.close();
  • 創(chuàng)建開銷:約5-20ms (取決于瀏覽器)
  • 內(nèi)存獨(dú)立:Worker崩潰不影響主線程
  • 自動回收:頁面關(guān)閉時自動銷毀

底層實現(xiàn)差異(瀏覽器引擎)

瀏覽器引擎線程模型實現(xiàn)特點
ChromiumBlink渲染引擎 + V8隔離實例每個Worker獨(dú)立V8實例
FirefoxSpiderMonkey獨(dú)立上下文共享JIT編譯器但隔離堆棧
SafariJavaScriptCore獨(dú)立虛擬機(jī)精細(xì)內(nèi)存管理

性能優(yōu)化要點

  1. 線程復(fù)用‌:避免頻繁創(chuàng)建/銷毀 (線程池模式)
  2. 批量通信‌:合并多次消息傳遞
  3. 高效數(shù)據(jù)結(jié)構(gòu)‌:優(yōu)先使用TypedArray
  4. 負(fù)載均衡‌:根據(jù)CPU核心數(shù)動態(tài)分配任務(wù)
  5. 超時控制‌:防止僵尸線程

Web Worker 通過線程隔離和高效通信機(jī)制,在保持JavaScript單線程編程模型的同時,實現(xiàn)了真正的并行計算能力,成為現(xiàn)代Web應(yīng)用性能優(yōu)化的關(guān)鍵基礎(chǔ)設(shè)施。

webworker典型應(yīng)用場景

場景類型實例技術(shù)價值
大數(shù)據(jù)處理實時日志分析/金融統(tǒng)計避免遍歷海量數(shù)據(jù)阻塞 UI‌27
音視頻處理4K 視頻解碼/Canvas 濾鏡分離計算與渲染流程‌17
高頻交互優(yōu)化游戲物理引擎/傳感器數(shù)據(jù)處理減少主線程壓力‌25
預(yù)加載與緩存SPA 資源預(yù)載入結(jié)合 Service Worker 提升加載速度‌

webworker實操

寫在前面:為什么主線程執(zhí)行大量的同步運(yùn)算會導(dǎo)致頁面卡頓?

瀏覽器默認(rèn)會有一個刷新頻率,這和個人電腦的默認(rèn)刷新率有關(guān),一般默認(rèn)為60HZ,也就是瀏覽器頁面會一秒鐘刷新60次,計算下來差不多每16ms就要刷新一次,才能保證頁面上所有的樣式和布局以及DOM節(jié)點信息是最新的,如果主線程此時運(yùn)行大量運(yùn)算,超過16ms,就會造成渲染阻塞。這就是需要用webworker分?jǐn)傊骶€程大量運(yùn)算的原因,至于每個webworker運(yùn)行多久不需要我們擔(dān)心,因為它在其他線程上,每個worker都是一個新線程,它不在js主線程上,它的運(yùn)行不會阻塞頁面渲染。

細(xì)節(jié)點補(bǔ)充:

1.如何查看自己電腦上的實際cpu核數(shù)與邏輯處理器核數(shù)

任務(wù)管理器>性能面板>內(nèi)核數(shù)與邏輯處理器數(shù)(一般邏輯處理器數(shù)會比真實內(nèi)核數(shù)要多)

2.電腦屏幕刷新率查看:

設(shè)置>系統(tǒng)>屏幕>高級顯示器設(shè)置>刷新率

因為webworker屬于web API,所以必須要運(yùn)行在瀏覽器環(huán)境下,需要通過live-server插件運(yùn)行示例html或者將相關(guān)代碼放置在一個vue或react模板工程中執(zhí)行

index.html內(nèi)容

<!doctype html>
<html lang="en">
  <body>
    <div id="app"></div>
    <!-- 啟用webworker效果 -->
     <script src="fiberMain.js"></script>
     <!-- 不啟用webworker效果 -->
     <!-- <script src="fiberWithout.js"></script> -->
  </body>
</html>

fiberMain.js 

// 主線程代碼,引用fiberWorker.js作為worker線程執(zhí)行代碼,實現(xiàn)大量cpu密集型運(yùn)算從主線程中拆分至worker線程中。

const startTime = Date.now();
// 動態(tài)啟用本機(jī)電腦上的cpu邏輯處理器核數(shù)并發(fā)執(zhí)行多個線程
const workCount = navigator.hardwareConcurrency || 4;
const fiberArr = Array(50).fill().map((_, index)=> 30 + index);
// 創(chuàng)建多個worker示例
const workers = Array(workCount).fill().map(() => new Worker('./fiberWorker.js'))
const chunkSize = Math.ceil(fiberArr.length / workCount);
// 任務(wù)切片分配給各個worker
workers.forEach((worker, i) => {
  const start = i * chunkSize;
  const chunk = fiberArr.slice(start, start + chunkSize);
  worker.postMessage({chunk, id : i});
  worker.onmessage = (e) => {
    // 每個worker運(yùn)算結(jié)束后worker的單獨(dú)耗時
    console.log('每一個worker計算結(jié)果結(jié)束完成后經(jīng)過的毫秒數(shù)::', (Date.now() - startTime));
  }
  worker.onerror = function (err) {
    console.error(err)
  }
})
// 主線程代碼執(zhí)行到這里的耗時
console.log('主線程同步代碼執(zhí)行完成后的耗時毫秒數(shù):::', (Date.now() - startTime))

fiberWorker.js   worker線程所要執(zhí)行的邏輯代碼,需要和fibermain.js搭配使用

// worker計算邏輯,斐波那契遞歸數(shù)列計算
self.onmessage = (e) => {
  const res = e.data.chunk.map(n => fibonacci(n))
  self.postMessage({res, id: e.data.id})
}
// 斐波那契計算函數(shù)(模擬耗時操作)
function fibonacci(n) {
  if (n <= 1) return n; // 基線條件:fib(0)=0, fib(1)=1
  return fibonacci(n - 1) + fibonacci(n - 2); // 遞歸調(diào)用
}

fiberWithout.js 

//  無worker線程,大量的遞歸運(yùn)算直接運(yùn)行在主線程中的寫法,主線程同步執(zhí)行大量運(yùn)算導(dǎo)致耗時很長,大概2000ms,會嚴(yán)重阻塞每16ms就要執(zhí)行一次的頁面渲染,導(dǎo)致頁面和用戶交互異??D。

//  不用worker,主線程單線程計算
const startTime = Date.now();
const fiberArr = Array(22).fill().map((_, index)=> 20 + index);
function fibonacci(n) {
  return n <= 2 ? n : fibonacci(n - 1) + fibonacci(n - 2);
}
const res = fiberArr.map(n => fibonacci(n));
console.log('同步計算的最終結(jié)果::', res);
console.log('主線程同步計算的耗時毫秒數(shù):::', (Date.now() - startTime));

fiberWithout.js 代碼在主線程上運(yùn)行相同的斐波那契數(shù)列計算邏輯耗時2013ms

fiberMain.js 配合 fiberWorker.js 在主線程上運(yùn)行相關(guān)代碼大大縮短同步代碼等待執(zhí)行時間,因為把大量的cpu密集型(遞歸回調(diào))運(yùn)算放置在了多個worker中運(yùn)算,所以主線程的同步代碼執(zhí)行很快,耗時2ms,但是這并不意味這worker內(nèi)單個線程中的運(yùn)算很快速,實際每個worker運(yùn)算耗時加著線程間的通信,單個worker最長執(zhí)行總耗時2064ms。

為什么要啟用worker,因為js主線程是單線程,js執(zhí)行與頁面渲染全在主線程上執(zhí)行,js同步代碼執(zhí)行過長會導(dǎo)致渲染阻塞,導(dǎo)致頁面卡頓,如果把上面的運(yùn)算邏輯放在主線程中執(zhí)行(也就是fiberWithout.js這種寫法),那么會導(dǎo)致頁面有2000多ms的渲染阻塞,因為js主線程需要每16ms就要運(yùn)行一次頁面渲染邏輯。所以會導(dǎo)致頁面卡頓,造成頁面渲染不及時以及用戶交互得不到及時響應(yīng)。

把大量的運(yùn)算分散到多個worker中,相當(dāng)于把主線程的大量運(yùn)算分?jǐn)偟搅似渌€程中,縮減主線程同步代碼至2ms,不會造成頁面卡頓。至于每個worker運(yùn)行2000ms那不是我們關(guān)心的重點,worker就是用來分?jǐn)傊骶€程的運(yùn)算負(fù)擔(dān)的,防止頁面卡頓。

webworker技術(shù)限制與注意事項

1.無法操作 DOM

Worker 線程無法訪問 windowdocument 等對象,需通過 postMessage 與主線程通信‌

2.通信成本控制

頻繁跨線程傳遞大數(shù)據(jù)(如圖像二進(jìn)制流)可能抵消性能優(yōu)勢,需采用 Transferable Objects 優(yōu)化

// 高效傳遞 ArrayBuffer
worker.postMessage(buffer, [buffer]); 

總結(jié)

到此這篇關(guān)于JS中webworker的作用與實操的文章就介紹到這了,更多相關(guān)JS webworker詳解內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

最新評論

马龙县| 玉门市| 湖南省| 霍州市| 同江市| 阿勒泰市| 丰顺县| 禹州市| 启东市| 原平市| 长武县| 汝城县| 江都市| 阿坝| 龙门县| 绥化市| 台湾省| 新巴尔虎左旗| 斗六市| 莱州市| 永福县| 平陆县| 兰西县| 高淳县| 雷山县| 古交市| 明光市| 石屏县| 德惠市| 浑源县| 固安县| 临沭县| 南江县| 龙川县| 泰和县| 阳春市| 蒙自县| 科技| 静海县| 宿迁市| 哈尔滨市|