国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

2023 年的 Web Worker 項(xiàng)目實(shí)踐

這篇具有很好參考價(jià)值的文章主要介紹了2023 年的 Web Worker 項(xiàng)目實(shí)踐。希望對(duì)大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請(qǐng)大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問。

目錄

前言

引入 Web Worker

Worker 實(shí)踐

Worker 到底有多難用

類庫(kù)調(diào)研

有類庫(kù)加持的 worker 現(xiàn)狀

向著舒適無(wú)感的 worker 編寫前進(jìn)

1. 抽取依賴,管理編譯和更新:

2. 定義公共調(diào)用函數(shù),引入所打包的依賴并串聯(lián)流程:

3. 優(yōu)化語(yǔ)法支持

4. 其他問題

總結(jié)

參考資料


前言

????Web Workers?是 2009 年就已經(jīng)提案的老技術(shù),但是在很多項(xiàng)目中的應(yīng)用相對(duì)較少,常見一些文章討論如何寫 demo ,但很少有工程化和項(xiàng)目級(jí)別的實(shí)踐,本文會(huì)結(jié)合?Web Workers?在京東羚瓏的程序化設(shè)計(jì)項(xiàng)目中的實(shí)踐,分享一下在當(dāng)下的 2023 年,關(guān)于?worker?融入項(xiàng)目的一些思考和具體的實(shí)現(xiàn)方式,涉及到的 demo 已經(jīng)放在 github 上附在文末,可供參考。

????????先簡(jiǎn)單介紹下?Web Workers,它是一種可以運(yùn)行在 Web 應(yīng)用程序后臺(tái)線程,獨(dú)立于主線程之外的技術(shù)。眾所周知,JavaScript 語(yǔ)言是單線程模型的,而通過使用?Web Workers,我們可以創(chuàng)造多線程環(huán)境,從而可以發(fā)揮現(xiàn)代計(jì)算機(jī)的多核 CPU 能力,在應(yīng)對(duì)規(guī)模越來(lái)越大的 Web 程序時(shí)也有較多收益。

????????Web Workers 宏觀語(yǔ)義上包含了三種不同的 Worker:DedicatedWorker(專有worker)、?SharedWorker(共享Worker)、?ServiceWorker,本文討論的是第一種,其他兩種大家可以自行研究一下。

引入 Web Worker

當(dāng)引入新技術(shù)時(shí),通常我們會(huì)考慮的問題有:

????????1、兼容性如何?

????????2、使用場(chǎng)景在哪?

問題 1,Web Workers 是 2009 年的提案,2012 年各大瀏覽器已經(jīng)基本支持,11 年過去了,現(xiàn)在使用已經(jīng)完全沒有問題啦

2023 年的 Web Worker 項(xiàng)目實(shí)踐

問題 2,主要考慮了以下 3 點(diǎn):

  1. ·Worker API?的局限性:同源限制、無(wú) DOM 對(duì)象、異步通信,因此適合不涉及 DOM 操作的任務(wù)

  2. ·Worker?的使用成本:創(chuàng)建時(shí)間 + 數(shù)據(jù)傳輸時(shí)間;考慮到可以預(yù)創(chuàng)建,可以忽略創(chuàng)建時(shí)間,只考慮數(shù)據(jù)傳輸成本,這里可參考 19 年的一個(gè)測(cè)試?Is postMessage slow[1]?,簡(jiǎn)要結(jié)論是比較樂觀的,大部分設(shè)備和數(shù)據(jù)情況下速度不是瓶頸

  3. ·任務(wù)特點(diǎn):需要是可并行的多任務(wù),為了充分利用多核能力,可并行的任務(wù)數(shù)越接近 CPU 數(shù)量,收益會(huì)越高。多線程場(chǎng)景的收益計(jì)算,可以參考?Amdahl?公式,其中?F?是初始化所需比例,N?是可并行數(shù):

    2023 年的 Web Worker 項(xiàng)目實(shí)踐

綜上結(jié)論是,可并行的計(jì)算密集型任務(wù)適合用?Worker?來(lái)做。

不過 github 上我搜羅了一圈,也發(fā)現(xiàn)有一些不局限于此,頗有創(chuàng)意的項(xiàng)目,供大家打開思路:

  1. ·redux 挪到了 worker 內(nèi)[2]

  2. ·dom 挪到了 worker 內(nèi)[3]

  3. ·可使用多核能力的框架[4]

Worker 實(shí)踐

????????介紹完?worker?,一個(gè)問題出現(xiàn)了:為什么一個(gè)兼容性良好,能夠發(fā)揮并發(fā)能力的技術(shù)(聽起來(lái)很有誘惑力),到現(xiàn)在還沒有大規(guī)模使用呢?

????????我理解有 2 個(gè)原因:一是暫無(wú)匹配度完美的使用場(chǎng)景,因此引入被擱置了;二是?worker api?設(shè)計(jì)得太難用,參考很多 demo 看,限制多配置還麻煩,讓人望而卻步。本文會(huì)主要著力于第二點(diǎn),希望給大家的?worker?實(shí)踐提供一些成熟的工程化思路。

????????至于第一點(diǎn)理由,在如此卷的前端領(lǐng)域,當(dāng)你手中已經(jīng)有了一把好用的錘子,還找不到那顆需要砸的釘子嗎?

Worker 到底有多難用

下面是一個(gè)原始?worker?的調(diào)用示例,上面是主線程文件,下面是?worker?文件:

//?index.js
const?worker?=?new?Worker('./worker.js')
worker.onmessage?=?function?(messageEvent)?{
??console.log(messageEvent)
}
//?worker.js
importScripts('constant.js')
function?a()?{
??console.log('test')
}

其中問題有:

  1. ·postMessage?傳遞消息的方式不適合現(xiàn)代編程模式,當(dāng)出現(xiàn)多個(gè)事件時(shí)就涉及分拆解析和解決耦合問題,因此需要改造

  2. ·新建?worker?需要單獨(dú)文件,因此項(xiàng)目?jī)?nèi)需要處理打包拆分邏輯,獨(dú)立出?worker?文件

  3. ·worker?內(nèi)可支持定義函數(shù),可通過importScript?方式引入依賴文件,但是都獨(dú)立于主線程文件,依賴和函數(shù)的復(fù)用都需要改造

  4. ·多線程環(huán)境必然涉及同步運(yùn)行多個(gè)?worker,多?worker?的啟動(dòng)、復(fù)用和管理都需要自行處理

看完這么多問題,有沒有感覺頭很大,一個(gè)設(shè)計(jì)這樣原始的 api,如何舒服的使用呢?

類庫(kù)調(diào)研

????????首先可以想到的就是借助成熟類庫(kù)的力量,下面表格是較為常見的幾款?worker?類庫(kù),其中我們可能會(huì)關(guān)注的關(guān)鍵能力有:

  1. ·通信是否有包裝成更好用的方式,比如?promise?化或者?rpc?化

  2. ·是否可以動(dòng)態(tài)創(chuàng)建函數(shù)——可以增加?worker?靈活性

  3. ·是否包含多?worker?的管理能力,也就是線程池

  4. ·考慮?node?的使用場(chǎng)景,是否可以跨端運(yùn)行

2023 年的 Web Worker 項(xiàng)目實(shí)踐

????????比較之下,workerpool[5]?勝出,它也是個(gè)年紀(jì)很大的庫(kù)了,最早的代碼提交在 6 年前,不過實(shí)踐下來(lái)沒有大問題,下文都會(huì)在使用它的基礎(chǔ)上繼續(xù)討論。

有類庫(kù)加持的 worker 現(xiàn)狀

????????通過使用?workerpool,我們可以在主線程文件內(nèi)新建?worker;它自動(dòng)處理多?worker?的管理;可以執(zhí)行?worker?內(nèi)定義好的函數(shù)?a;可以動(dòng)態(tài)創(chuàng)建一個(gè)函數(shù)并傳入?yún)?shù),讓?worker?來(lái)執(zhí)行。

//?index.js
import?workerpool?from?'workerpool'
const?pool?=?workerpool.pool('./worker.js')
//?執(zhí)行一個(gè)?worker?內(nèi)定義好的函數(shù)
pool.exec('a',?[1,?2]).then((res)?=>?{
??console.log(res)
})
//?執(zhí)行一個(gè)自定義函數(shù)
pool
??.exec(
????(x,?y)?=>?{
??????return?x?+?y
????},?//?自定義函數(shù)體
????[1,?2],?//?自定義函數(shù)參數(shù)
??)
??.then((res)?=>?{
????console.log(res)
??})
//?worker.js
importScripts('constant.js')
function?a()?{
??console.log('test')
}

但是這樣還不夠,為了可以舒適的寫代碼,我們需要進(jìn)一步改造。

向著舒適無(wú)感的 worker 編寫前進(jìn)

我們期望的目標(biāo)是:

  1. ·足夠靈活:可以隨意編寫函數(shù),今天我想計(jì)算1+1,明天我想計(jì)算1+2,這些都可以動(dòng)態(tài)編寫,最好它可以直接寫在主線程我自己的文件里,不需要我跑到?worker?文件里去改寫;

  2. ·足夠強(qiáng)大:我可以使用公共依賴,比如?lodash?或者是項(xiàng)目里已經(jīng)定義好的某些公共函數(shù)。

????????考慮到?workerpool?具備了動(dòng)態(tài)創(chuàng)建函數(shù)的能力,第一點(diǎn)已經(jīng)可以實(shí)現(xiàn);而第二點(diǎn)關(guān)于依賴的管理,則需要自行搭建,接下來(lái)介紹搭建步驟。

1. 抽取依賴,管理編譯和更新:

????????新增一個(gè)依賴管理文件worker-depts.js,可按照路徑作為 key 名構(gòu)建一個(gè)聚合依賴對(duì)象,然后在?worker?文件內(nèi)引入這份依賴

//?worker-depts.js
import?*?as?_?from?'lodash-es'
import?*?as?math?from?'../math'

const?workerDepts?=?{
??_,
??'util/math':?math,
}

export?default?workerDepts
//?worker.js
import?workerDepts?from?'../util/worker/worker-depts'

2. 定義公共調(diào)用函數(shù),引入所打包的依賴并串聯(lián)流程:

????worker?內(nèi)定義一個(gè)公共調(diào)用函數(shù),注入 worker-depts 依賴,并注冊(cè)在?workerpool?的方法內(nèi)

//?worker.js
import?workerDepts?from?'../util/worker/worker-depts'

function?runWithDepts(fn:?any,?...args:?any)?{
??var?f?=?new?Function('return?('?+?fn?+?').apply(null,?arguments);')
??return?f.apply(f,?[workerDepts].concat(args))
}

workerpool.worker({
??runWithDepts,
})

主線程文件內(nèi)定義相應(yīng)的調(diào)用方法,入?yún)⑹亲远x函數(shù)體和該函數(shù)的參數(shù)列表

//?index.js
import?workerpool?from?'workerpool'
export?async?function?workerDraw(fn,?...args)?{
??const?pool?=?workerpool.pool('./worker.js')
??return?pool.exec('runWithDepts',?[String(fn)].concat(args))
}

????????完成以上步驟,就可以在項(xiàng)目任意需要調(diào)用?worker?的位置,像下面這樣。自定義函數(shù)內(nèi)容,引用所需依賴(已注入在函數(shù)第一個(gè)參數(shù)),進(jìn)行使用了。

????????這里我們引用了一個(gè)項(xiàng)目?jī)?nèi)的公共函數(shù)?fibonacci,也引用了一個(gè)?lodash?的?map?方法,都可以在depts?對(duì)象上取到

//?項(xiàng)目?jī)?nèi)需使用worker時(shí)
const?res?=?await?workerDraw(
??(depts,?m,?n)?=>?{
????const?{?map?}?=?depts['_']
????const?{?fibonacci?}?=?depts['util/math']
????return?map([m,?n],?(num)?=>?fibonacci(num))
??},
??input1,
??input2,
)

3. 優(yōu)化語(yǔ)法支持

????????沒有語(yǔ)法支持的依賴管理是很難用的,通過對(duì)?workerDraw?進(jìn)行?ts?語(yǔ)法包裝,可以實(shí)現(xiàn)在使用時(shí)的依賴提示:

import?workerpool?from?'workerpool'
import?type?TDepts?from?'./worker-depts'

export?async?function?workerDraw<T?extends?any[],?R>(fn:?(depts:?typeof?TDepts,?...args:?T)?=>?Promise<R>?|?R,?...args:?T)?{
??const?pool?=?workerpool.pool('./worker.js')
??return?pool.exec('runWithDepts',?[String(fn)].concat(args))
}

然后就可以在使用時(shí)獲取依賴提示:

2023 年的 Web Worker 項(xiàng)目實(shí)踐

4. 其他問題

????????新增了?worker?以后,出現(xiàn)了?window和?worker?兩種運(yùn)行環(huán)境,如果你恰好和我一樣需要兼容?node?端運(yùn)行,那么運(yùn)行環(huán)境就是三種,原本我們通常判斷 window 環(huán)境使用的也許是?typeof window === 'object'這樣,現(xiàn)在不夠用了,這里可以改為 globalThis 對(duì)象,它是三套環(huán)境內(nèi)都存在的一個(gè)對(duì)象,通過判斷globalThis.constructor.name的值,值分別是'Window' / 'DedicatedWorker'/ 'Object',從而實(shí)現(xiàn)環(huán)境的區(qū)分

總結(jié)

????????通過使用?workerpool,添加依賴管理和構(gòu)建公共?worker?調(diào)用函數(shù),我們實(shí)現(xiàn)了一套按需調(diào)用,靈活強(qiáng)大的?worker?使用方式。

????????在京東羚瓏的程序化設(shè)計(jì)項(xiàng)目中,通過把 skia 圖形繪制部分逐步改造為?worker內(nèi)調(diào)用,我們實(shí)現(xiàn)了整體服務(wù)耗時(shí)降低 75% 的效果,收益還是非常不錯(cuò)的。

????????文中涉及的代碼示例都已放在?github[6]?上,內(nèi)有?vite?和?webpack?兩個(gè)完整實(shí)現(xiàn)版本,感興趣的小伙伴可以 clone 下來(lái)參照著看~

參考資料


[1] Is postMessage slow:?https://dassur.ma/things/is-postmessage-slow/

[2] redux 挪到了 worker 內(nèi):?https://blog.axlight.com/posts/off-main-thread-react-redux-with-performance

[3] dom 挪到了 worker 內(nèi):?https://github.com/ampproject/worker-dom

[4] 可使用多核能力的框架:?https://github.com/neomjs/neo

[5] workerpool:?https://github.com/josdejong/workerpool

[6] github:?https://github.com/Silencesnow/worker-demo-2022

[7] MDN Web Workers API:?https://developer.mozilla.org/zh-CN/docs/Web/API/Web_Workers_API

[8] workerpool:?https://github.com/josdejong/workerpool

[9] 前端項(xiàng)目上 Web Worker 實(shí)踐:?https://www.youtube.com/watch?v=AEpG-3XXrjk

[10] Web Worker 文獻(xiàn)綜述:?https://juejin.cn/post/6854573213297410062文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-464918.html

到了這里,關(guān)于2023 年的 Web Worker 項(xiàng)目實(shí)踐的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來(lái)自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場(chǎng)。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請(qǐng)注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請(qǐng)點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • 實(shí)踐解決:IDEA2022版本創(chuàng)建Maven項(xiàng)目時(shí)沒有出現(xiàn)src目錄

    實(shí)踐解決:IDEA2022版本創(chuàng)建Maven項(xiàng)目時(shí)沒有出現(xiàn)src目錄

    大家好,我是小白DunkIT,今天給大家分享一下我最近遇到的IDEA2022.3版本創(chuàng)建Maven項(xiàng)目時(shí)出現(xiàn)沒有src目錄的問題。 問題:IDEA創(chuàng)建Maven項(xiàng)目時(shí)沒有出現(xiàn)src目錄 創(chuàng)建Maven項(xiàng)目 新版本的IDEA創(chuàng)建是選用的是Maven Archetype,選擇這個(gè)也是和Maven一樣的。按照這樣流程創(chuàng)建完成之后的的架構(gòu)

    2024年02月11日
    瀏覽(94)
  • 如何設(shè)計(jì)一個(gè)優(yōu)秀的 Go Web 項(xiàng)目目錄結(jié)構(gòu)

    Go 語(yǔ)言作為一門高效、簡(jiǎn)潔、并發(fā)安全的語(yǔ)言,越來(lái)越受到開發(fā)者們的青睞,特別是在 Web 開發(fā)及云原生領(lǐng)域。而對(duì)于一個(gè)大型的 Go Web 項(xiàng)目而言,一個(gè)優(yōu)秀的目錄結(jié)構(gòu)設(shè)計(jì)是必不可少的。它可以幫助我們更好地組織代碼、減少冗余、提高可維護(hù)性和可擴(kuò)展性。 在本文中,我

    2024年02月12日
    瀏覽(20)
  • 解決微信小程序“app.json: [“workers“] 字段需為 目錄“錯(cuò)誤及worker的使用

    解決微信小程序“app.json: [“workers“] 字段需為 目錄“錯(cuò)誤及worker的使用

    我們?nèi)绻龅絒 miniprogram/app.json 文件內(nèi)容錯(cuò)誤] miniprogram/app.json: [“workers”] 字段需為 目錄(env: Windows,mp,1.06.2209190; lib: 2.21.4)這樣的錯(cuò)誤,那么一定是我們?cè)赼pp.json中定義了這個(gè)字段。 1.方法一: 找到這個(gè)字段直接刪除即可。 2.方法二: 在你的項(xiàng)目目錄中補(bǔ)充一個(gè)對(duì)應(yīng)的worker

    2024年02月12日
    瀏覽(31)
  • 梳理 Web Worker 及實(shí)戰(zhàn)場(chǎng)景

    有一些前端技術(shù)點(diǎn),即使以前用過,但沒有自己動(dòng)手歸納總結(jié)過,許久還是要回過頭來(lái)還是需要重新梳理。于是,本文就來(lái)梳理一下 Web Worker。 由于JavaScript語(yǔ)言采用的是單線程,同一時(shí)刻只能做一件事,如果有多個(gè)同步計(jì)算任務(wù)執(zhí)行,則在這段同步計(jì)算邏輯執(zhí)行完之前,它下

    2024年02月14日
    瀏覽(21)
  • HTML5 Web Worker

    HTML5 Web Worker是一種瀏覽器提供的JavaScript多線程解決方案,它允許在后臺(tái)運(yùn)行獨(dú)立于頁(yè)面主線程的腳本,從而避免阻塞頁(yè)面的交互和渲染。Web Worker可以用于執(zhí)行計(jì)算密集型任務(wù)、處理大量數(shù)據(jù)、實(shí)現(xiàn)并行計(jì)算等,從而提升前端應(yīng)用的性能和響應(yīng)能力。 特點(diǎn)和用途: 多線程:

    2024年02月14日
    瀏覽(19)
  • JavaScript Web Worker用法指南

    JavaScript Web Worker用法指南

    ????? 個(gè)人主頁(yè): 《愛蹦跶的大A阿》 ?? 當(dāng)前正在更新專欄: 《VUE》?、《JavaScript保姆級(jí)教程》、《krpano》 ?? ? ????????Web Worker可以將耗時(shí)任務(wù)放到后臺(tái)執(zhí)行,避免阻塞UI。本文將詳細(xì)介紹Web Worker的用法,讓你可以提升web應(yīng)用性能。 通過本文你將學(xué)習(xí): Web Worker的工作

    2024年01月18日
    瀏覽(24)
  • Web Worker的概念、用法、使用場(chǎng)景

    Web Worker的概念、用法、使用場(chǎng)景

    ? 目錄 1.?簡(jiǎn)介 2.?適用場(chǎng)景 2.1 復(fù)雜計(jì)算 2.2?后臺(tái)下載 2.3?數(shù)據(jù)處理 2.4?實(shí)時(shí)通信 3.?代碼示例 3.1 Worker特性檢測(cè) 3.2 Worker API 3.3 SharedWorker API 3.4?創(chuàng)建 JavaScript 文件 3.5?創(chuàng)建 Web Worker 4. 總結(jié) Web Worker ?使得在一個(gè)獨(dú)立于 Web 應(yīng)用程序主執(zhí)行線程的后臺(tái)線程中運(yùn)行腳本操作成為可

    2024年02月08日
    瀏覽(21)
  • 如何使用 Web Worker 處理大文件上傳

    如何使用 Web Worker 處理大文件上傳

    博主貓頭虎的技術(shù)世界 ?? 歡迎來(lái)到貓頭虎的博客 — 探索技術(shù)的無(wú)限可能! 專欄鏈接 : ?? 精選專欄 : 《面試題大全》 — 面試準(zhǔn)備的寶典! 《IDEA開發(fā)秘籍》 — 提升你的IDEA技能! 《100天精通Golang》 — Go語(yǔ)言學(xué)習(xí)之旅! 領(lǐng)域矩陣 : ?? 貓頭虎技術(shù)領(lǐng)域矩陣 : 深入探索

    2024年01月23日
    瀏覽(20)
  • 【2023年的就業(yè)形勢(shì)依舊嚴(yán)峻】

    【2023年的就業(yè)形勢(shì)依舊嚴(yán)峻】

    2023年口罩放開的第一年,也是第一個(gè)招聘會(huì),擠滿了求職者和用人單位,大多數(shù)都是想著重新開始,抓住金三銀四的好時(shí)機(jī),找到心儀的工作和符合崗位要求的人才,一起整裝出發(fā)。我們理想的狀態(tài)是,經(jīng)濟(jì)已經(jīng)在恢復(fù)了,那么就業(yè)市場(chǎng)也應(yīng)該恢復(fù)了。然而現(xiàn)實(shí)是殘酷的,海

    2024年02月04日
    瀏覽(23)
  • html5學(xué)習(xí)筆記18-web存儲(chǔ)、web sql、web worker

    https://www.runoob.com/html/html5-webstorage.html HTML5 web 存儲(chǔ),可替代 cookie 的本地存儲(chǔ)方式。 客戶端存儲(chǔ)數(shù)據(jù)的兩個(gè)對(duì)象:localStorage網(wǎng)站的 sessionStorage窗口的 web db sql web worker

    2024年02月10日
    瀏覽(20)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請(qǐng)作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包