You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React中大型二维状态数组引发卡顿的优化方案咨询

React大型二维数组绘图应用性能优化方案

针对大型二维数组导致React应用卡顿的问题,可通过以下核心方向优化:

1. 修复初始状态的引用共享问题

原代码中Array(width).fill(Array(length).fill(false))会让所有列共享同一个数组实例,不仅会导致状态更新异常,还会引发不必要的组件重渲染。修改为:

import { useState, useCallback, memo } from "react";

function App() {
  const width = 200;
  const length = 200;
  // 每列都是独立数组,避免引用共享
  const [selected, setSelected] = useState(() => 
    Array.from({ length: width }, () => Array(length).fill(false))
  );
  // ...
}

2. 优化状态更新逻辑

原更新方式会创建整列的新数组,内存开销大。改为仅复制并修改目标元素,同时用useCallback缓存事件处理函数,避免每次渲染创建新函数:

const columnSquareSelected = useCallback((columnInd, squareInd) => {
  setSelected(prev => {
    // 仅复制需要修改的列
    const newColumn = [...prev[columnInd]];
    newColumn[squareInd] = true;
    // 仅复制外层数组的必要部分
    return [...prev.slice(0, columnInd), newColumn, ...prev.slice(columnInd + 1)];
  });
}, []);

3. 阻止不必要的组件重渲染

用React.memo包裹Square和Column组件,只有当props真正变化时才触发重渲染:

const Square = memo(({ squareVal, setSquareVal }) => {
  return (
    <button
      className={`h-1 w-1 ${squareVal ? "bg-red-600" : "bg-gray-300"}`}
      onMouseEnter={setSquareVal}
    ></button>
  );
});

const Column = memo(({ columnArr, columnInd, columnSquareSelected }) => {
  return (
    <div className="flex flex-col">
      {columnArr.map((sqrVal, sqrInd) => (
        <Square
          key={`${columnInd}-${sqrInd}`}
          squareVal={sqrVal}
          setSquareVal={() => columnSquareSelected(columnInd, sqrInd)}
        />
      ))}
    </div>
  );
});

4. 引入虚拟滚动(核心优化)

当元素数量达到40000个时,过多DOM节点是卡顿的主要原因。使用虚拟滚动只渲染视口内的元素,以react-window为例:
首先安装依赖:

npm install react-window

然后修改App组件的渲染逻辑:

import { FixedSizeList as List } from 'react-window';

function App() {
  // ... 状态和事件处理函数不变

  // 渲染单列的回调
  const renderColumn = ({ index, style }) => {
    return (
      <div style={style}>
        <Column
          columnArr={selected[index]}
          columnInd={index}
          columnSquareSelected={columnSquareSelected}
        />
      </div>
    );
  };

  return (
    <>
      <div>
        <h1 className="text-5xl large font-semibold">Heart Rate Faker</h1>
        <h2 className="text-xl font-semibold">Create fake heart rate data</h2>
      </div>
      <div className="flex justify-center items-center">
        <List
          height={length} // 列总高度(每个Square占1px)
          width={width} // 总宽度(每个Column占1px)
          itemCount={width} // 列的数量
          itemSize={1} // 每列宽度
        >
          {renderColumn}
        </List>
      </div>
    </>
  );
}

5. 细节优化

  • 简化类名拼接:直接用模板字符串代替classNames函数,减少函数调用开销;
  • 优化key值:用${columnInd}-${sqrInd}代替空格拼接,避免潜在的key冲突。

内容的提问来源于stack exchange,提问作者Alan Ganser

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.02 19:13:22