前言
提到 WebWorker,可能有些小伙伴比較陌生,不知道是做什么的,甚至不知道使用場景,今天這篇文章就帶大家一起簡單了解一下什么是 webworker!
概念
WebWorker 實(shí)際上是運(yùn)行在瀏覽器后臺(tái)的一個(gè)單獨(dú)的線程,因此可以執(zhí)行一些耗時(shí)的操作而不會(huì)阻塞主線程。WebWorker 通過與主線程之間傳遞消息實(shí)現(xiàn)通信,這種通信是雙向的。WebWorker不能直接訪問 DOM,也不能使用像 window 對(duì)象這樣的瀏覽器接口對(duì)象,但可以使用一些WebWorker 標(biāo)準(zhǔn)接口和 Navigator 對(duì)象的部分屬性和方法。
為什么使用WebWorker?
提高應(yīng)用響應(yīng)能力:主線程被獨(dú)占執(zhí)行一些耗時(shí)的計(jì)算或操作時(shí),會(huì)導(dǎo)致UI無響應(yīng)。WebWorker 可以把這些任務(wù)轉(zhuǎn)移到后臺(tái)線程,從而保證主線程的運(yùn)行,提高應(yīng)用的響應(yīng)能力。
充分利用多核CPU:現(xiàn)代CPU都是多核的,WebWorker 可以讓 Web 應(yīng)用利用多核 CPU 的并行計(jì)算能力,充分發(fā)揮計(jì)算機(jī)硬件性能。
避免渲染阻塞:JavaScript 運(yùn)行在主線程,如果主線程一直占用,就無法執(zhí)行 GUI 渲染任務(wù),導(dǎo)致界面渲染受阻。WebWorker 把一些費(fèi)時(shí)任務(wù)分流到后臺(tái)線程就可以避免這一問題。
后臺(tái)持續(xù)運(yùn)行:WebWorker 所在后臺(tái)線程可持續(xù)運(yùn)行,即使頁面被掛起或最小化,任務(wù)仍在后臺(tái)執(zhí)行,非常適合一些需要長時(shí)間運(yùn)行的操作。
使用場景
一般來說,當(dāng)遇到如下幾種情況時(shí)可以考慮使用 WebWorker:
大量數(shù)據(jù)的計(jì)算/處理:比如圖像處理、數(shù)據(jù)分析等
長時(shí)間運(yùn)行的操作:如一些復(fù)雜的數(shù)學(xué)計(jì)算
非阻塞式操作:希望執(zhí)行一些耗時(shí)操作時(shí)不阻塞主線程
示例
假設(shè)我們有一個(gè)需要計(jì)算斐波那契數(shù)列的任務(wù),我們可以使用 Web Worker 來進(jìn)行計(jì)算,以避免阻塞主線程。以下是一個(gè)簡單的示例:
?主線程
主線程創(chuàng)建 worker 實(shí)例,向子線程通過 postMessage 發(fā)送消息,通過 onmessage 監(jiān)聽子線程返回的數(shù)據(jù)。
const myWorker = new Worker('./worker.js')
myWorker.onmessage = function (e) {
console.log('Fibonacci result:', e.data)
myWorker.postMessage(40) // 請(qǐng)求計(jì)算斐波那契數(shù)列的第40項(xiàng)
worker.js
在同級(jí)目錄下創(chuàng)建 worker.js文件,通過 onmessage 接收主線程發(fā)來的數(shù)據(jù),計(jì)算后通過postMessage 將計(jì)算結(jié)果返回主線程。
self.onmessage = function (e) {
for (let i = 2; i <= n; i++) {
運(yùn)行結(jié)果
可以看到主線程打印出 webworker 計(jì)算的運(yùn)行結(jié)果

Vue、React項(xiàng)目使用
接下來為大家演示 vue 以及 react 項(xiàng)目如何使用
Vue使用
vue版本:"vue": "^2.6.14",vue-cli版本:@vue/cli 5.0.8安裝 worker-loader
頁面使用
<template><div>我的頁面</div></template>
// 創(chuàng)建 WebWorker 實(shí)例
this.worker = new Worker(new URL('./worker.js', import.meta.url))
console.log('worker: ', this.worker)
this.worker.postMessage(40) // 請(qǐng)求計(jì)算斐波那契數(shù)列的第40項(xiàng)
this.worker.addEventListener('message', (event) => {
console.log('Fibonacci result:', event.data)
// 組件銷毀時(shí)終止 WebWorker
worker.js
self.addEventListener('message', (e) => {
for (let i = 2; i <= n; i++) {
效果

React使用
react版本: "react": "^18.2.0"
import React, { useEffect } from 'react'
// import WorkerScript from './worker.worker.js'
const worker = new Worker(new URL('./worker.worker.js', import.meta.url))
worker.onmessage = function (e) {
console.log('Fibonacci result:', e.data)
worker.postMessage(40) // 請(qǐng)求計(jì)算斐波那契數(shù)列的第40項(xiàng)
return () => worker.terminate()
效果

注意
由于我們?cè)陧?xiàng)目開發(fā)時(shí),使用不同的打包工具(vite/webpack)。幸運(yùn)的是,最新版的vite/webpack都支持Web Worker了。
我們可以通過:new URL()的方式 --vite/webpack都支持
總結(jié)
WebWorker是一種在 Web 應(yīng)用中實(shí)現(xiàn)多線程運(yùn)行的技術(shù),可以將耗費(fèi) CPU 的任務(wù)交給后臺(tái)線程處理,避免阻塞主線程,從而提高Web應(yīng)用的響應(yīng)性能和用戶體驗(yàn)。 總之,WebWorker的引入解決了Web應(yīng)用長期以來在單個(gè)線程中運(yùn)行所帶來的諸多問題,有效提升了Web應(yīng)用的運(yùn)行性能和用戶體驗(yàn)。
該文章在 2025/1/10 10:34:02 編輯過