也是用上webworker了

React 16.8,我自己写的的足球应用,问题是模态框没有立即弹出,反而是等了一会才弹出。

scss 复制代码
  useImperativeHandle(ref, () => ({
    showModal: (id: string) => {
      const newState = {
        ...state,
        id,
        teamCount: teamOddList.length,
        tableLoading: true,
        open: true,
      };
      setState(newState);
      setAddedItems(new Map());

      // 初始化已存在的奖金项目
      initializeAddedItems(id);

      getOddResultList(newState, teamOddList);
    },
  }));

我开始以为是 React 响应式设计导致的,因为此时 setState 的是异步的,虽然 showModal 中设置了 open 为 true,后续处理不当,还是会导致 open 隐式设置为 false

仔细检查一番发现没有,并且我已经把 newSate 传递过去了,通过注释代码发现,是getOddResultList导致的,其实在之前的写法中我是加了setTimeout的,只不过时间太久了忘记了为什么加。

如今再写一来觉得setTimeout这种解决方式并不好。而且延迟 20ms 是没用的,看起来像是在等计算完成后再显示模态框。

于是我问了下 Trace,他说是因为getOddResultList有大量的同步计算,建议我用 webworker 来处理。

  • 多重嵌套循环 :对每个球队的赔率信息进行多维度组合计算(胜平负、让球、比分、进球数、半场等)
  • 指数级复杂度 :通过递归函数 getTeamCombinationList 和 againForEach 生成所有可能的投注组合
  • 大量数据处理 :每个组合都需要计算赔率乘积,并进行排序
  • JavaScript 是单线程的,同步计算会完全阻塞主线程
  • 模态框的 open 状态虽然已设置为 true ,但 React 无法进行重新渲染
  • 用户界面会出现"卡顿",模态框无法立即显示

这个函数确实会消耗大量的时间,因为有 4 只球队会产生 9 百万种结果。

使用 webworker 的话,需要将 js 文件放到 public 目录下,通过onmessage来接收消息,通过postMessage来发送消息。

php 复制代码
self.onmessage = function (e) {
  const { teamOddList } = e.data;
  try {
    const result = calculateOddResultList(teamOddList);
    self.postMessage({ success: true, data: result });
  } catch (error) {
    self.postMessage({ success: false, error: error.message });
  }
};

在 jsx 文件中使用 webworker

ini 复制代码
useEffect(() => {
    // 创建 Web Worker

    workerRef.current = new Worker('/oddResultWorker.js');
    workerRef.current.onmessageerror = (e) => {
      console.error('Worker message error:', e);
    };

    // 监听 Worker 消息
    workerRef.current.onmessage = (e) => {
      const { success, data, error } = e.data;
      if (success) {
        allOddResultListRef.current = data;
        setState((preState) => ({
          ...preState,
          total: data.length,
          tableLoading: false,
          oddResultList: data.slice(
            (preState.currentPage - 1) * pageSize,
            preState.currentPage * pageSize
          ),
        }));
      } else {
        console.error('Worker error:', error);
      }
    };

    return () => {
      if (workerRef.current) {
        workerRef.current.terminate();
      }
    };
  }, []);

调用时

typescript 复制代码
    showModal: (id: string, teamOddList: Array<NFootball.ITeamRecordOdds>) => {
      ...
      setAddedItems(new Map());
      initializeAddedItems(id);

      workerRef.current.postMessage({ teamOddList });
    },
相关推荐
爱喝水的鱼丶2 小时前
SAP-ABAP:MM 模块库存管理开发:出入库增强、批次管理与库存盘点功能开发
性能优化·sap·abap·增强·开发运维·经验交流·mm模块
AI服务老曹3 小时前
告警回调不是配上就能跑:性能优化里的关键参数(视频分析接入飞书告警实践)
性能优化·ai视频分析告警接口·告警回调
触底反弹5 小时前
🔥 从执行上下文到 React 陷阱——彻底搞懂 JavaScript 闭包
javascript·react.js
李明卫杭州21 小时前
React 复合事件系统对比解析
前端·javascript·react.js
Cx330❀1 天前
【Linux网络】网络层 IP 协议:从网段划分到内核源码解析
大数据·linux·服务器·网络·tcp/ip·性能优化·langchain
yume_sibai1 天前
12-Rust 性能优化指南(性能分析 + 内存优化 + SIMD + 并发优化 + 编译器优化 + 基准测试)
开发语言·性能优化·rust
爱喝水的鱼丶1 天前
SAP-ABAP:SAP MM 模块物料主数据批量导入与增强开发:字段扩展、校验逻辑与批量导入工具开发
开发语言·性能优化·sap·abap·增强·经验交流·mm
白雾茫茫丶1 天前
Vibecoding 一个主题切换动画库:13 种揭幕方式
前端·vue.js·react.js
西瓜太郎4991 天前
别再手算 Token 成本:用 React 状态机做一个可追溯的模型费用计算器
react.js·typescript
RobinDevNotes1 天前
用 Profile 揪出大模型训练性能瓶颈
python·性能优化