uniapp中使用web-worker性能优化的分享

发布于:2025-07-05 ⋅ 阅读:(14) ⋅ 点赞:(0)

为什么要使用 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 } = res
    console.log('Worker 收到消息:', data)
    switch (type) {
      case WebWorkerTypeEnum.PROCESS_GPS_DATA:
        // 业务代码
        break
      case 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 worker
  worker.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处理复杂的数据,特别是数据两比较大的更新

网站公告

今日签到

点亮在社区的每一天
去签到