為什么要使用 web-workers
原因很簡單,將復雜的計算邏輯和耗時邏輯放到線程中運行,避免ui阻塞,防止卡頓問題
場景:本次運用于GPS 位置更新
接入小程序
注意事項:微信小程序中只允許存在一個 worker所以,需要再一個worker里面完成多個任務,或者在開心的woker時,需要關閉當前的worker
一,在static/workers 下放你需要的worker.js文件
gps-workers.js
//用于接收外部消息
worker.onMessage(function (res) {console.log('worker內部線程')console.log(res)//用于發送// worker.postMessage({// message: '收到worker的消息'// });const { type, data } = res;let result;switch (type) {case 'PROCESS_GPS_DATA': {result = processGpsData(res.data);break;}case 'PROCESS_POSITION': {result = filterPlayerPositions(data);break;}}worker.postMessage({data: result,type,});
});
// 處理GPS數據
function processGpsData(data) {// 業務代碼return data
}
// 篩選用戶
function filterPlayerPositions(data) {// 業務代碼return data
}
二,在pages.json中配置workers目錄
三,在頁面引入使用
// 注冊
// #ifdef MP
let worker: UniApp.Worker | null = null
try {worker = uni.createWorker('static/workers/gps-workers.js', {useExperimentalWorker: true,})worker.onMessage((res) => {const { type, data } = resconsole.log('Worker 收到消息:', data)switch (type) {case WebWorkerTypeEnum.PROCESS_GPS_DATA:// 業務代碼breakcase WebWorkerTypeEnum.PROCESS_POSITION:// 業務代碼break}})
} catch (e) {console.error('創建 Worker 失敗:', e)
}
// #endif// 發現消息給web-worker處理worker?.postMessage({data: {positions: cloneDeep(positionBsResult.list),players: cloneDeep(players.value),},type: WebWorkerTypeEnum.PROCESS_GPS_DATA,})
// 釋放
onUnload(() => {worker?.terminate()
})
優化后的對標
接入web
在未更改前,由于數據量大,信息更新除了接口請求,耗時在7s+,ui會卡頓,特別是第一次加載數據以及位置更新的時候,后面優化后基本達到毫秒級別
一,在適合的目錄創建
gps-worker.ts
// 處理 GPS 數據的邏輯
function processGpsData(data) {// 業務代碼。。。return data
}// 添加新的 worker 處理函數
function filterPlayerPositions(data: xxx) {// 業務代碼。。。return data
}// 修改消息監聽方式
globalThis.addEventListener('message', (e) => {const { type, data } = e.data;let result: any;switch (type) {case WebWorkerTypeEnum.PROCESS_GPS_DATA: {result = processGpsData(data);break;}case WebWorkerTypeEnum.PROCESS_POSITION: {result = filterPlayerPositions(data);break;}}globalThis.postMessage({data: result,type,});
});
// export default {} as typeof Worker & { new (): Worker };
export default null;
二,在需要的位置加載和使用
// 加載web workerworker.value = new Worker(new URL('../data/gps-worker.ts', import.meta.url), {type: 'module',});worker.value.addEventListener('message', (e) => {const { type, data } = e.data;if (type === WebWorkerTypeEnum.PROCESS_GPS_DATA) {// 處理 worker 返回的數據}});
總結
- 合理利用web-worker處理復雜的數據,特別是數據兩比較大的更新