React在极端套接字更新上执行速度慢

问题描述

我正在构建一个交易应用程序,并在服务器端使用节点并在客户端进行响应。我目前面临的问题是关于频繁更新的响应性能

我的过程描述如下。

我最常见的情况是两个表,显示选项数据调用和放置。每个表的最小行数为两行,最大为8行,因此总共一次最多可以有16行。每行最多可以有30列。

我使用套接字连接进行更新。每当一个简单的变化发生在任何选项列的发生从插座服务器的事件发射我将在客户端监听。

通过套接字在客户端获取数据后,我可以搜索要更新数据的特定行和列,然后使用旧数据和新数据重新构建所有16行的全部数据,然后分派操作。 ..这种更新非常频繁地发生,例如每毫秒1000到100的更新中的一次,并且由于整个表被重新渲染而导致我的应用程序变慢。

我正在使用Redux来管理我的React应用程序中的状态

解决方法

我不知道您为什么如此频繁地重新渲染组件,但是您可以尝试限制对redux存储的更新。这样,您将向用户显示所有最新数据,而不会增加CPU负担。

您可以使用throttle-debounce包来限制套接字回调。仅在自上次调用以来已过去了给定间隔的情况下,随后对调速函数的调用才会成功。

,

这是一个纯组件的示例,每秒更新约100次没有问题:

const { useState,memo,useEffect,useRef } = React;

const COLUMS = 31;
const ITEM_COUNT = COLUMS * COLUMS;
const TIMER = 10;
const COLORS = ['red','green','blue'];
const nextColor = ((current) => () =>
  COLORS[++current % COLORS.length])(0);
const next = ((num) => () => ++num % ITEM_COUNT)(-1);
const Item = memo(function Item({ color }) {
  return (
    <td
      style={{
        border: '1px solid black',minWidth: '20px',minHeight: '20px',backgroundColor: color,transitionDuration: '2s',transitionTimingFunction: 'ease-out',transitionProperty: 'color,background-color',}}
    >
      &nbsp;
    </td>
  );
});

const Row = memo(function Row({ items }) {
  return (
    <tr>
      {items.map((item) => (
        <Item key={item.id} color={item.color} />
      ))}
    </tr>
  );
});

const App = () => {
  const r = useRef(0);
  r.current++;
  const [data,setData] = useState(
    new Array(ITEM_COUNT)
      .fill('')
      .map((_,id) => ({ id,color: 'red' }))
      .reduce((result,item,index) => {
        if (index % COLUMS === 0) {
          result.push([]);
        }
        result[result.length - 1].push(item);
        return result;
      },[])
  );
  useEffect(() => {
    const i = setInterval(
      () =>
        setData((data) => {
          const change = next(),//id to change
            color = nextColor(); //new value for color
          return data.map(
            (items) =>
              //do not update items if id is not in this row
              items.find(({ id }) => id === change)
                ? //update the one item that has id of change
                  items.map(
                    (item) =>
                      item.id === change
                        ? { ...item,color } //change the color
                        : item //return the item unchanged
                  )
                : items //id is not in this row return items unchanged
          );
        }),TIMER
    );
    return () => clearInterval(i);
  },[]);
  return (
    <div>
      <h1>rendered: {r.current}</h1>
      <table>
        <tbody>
          {data.map((items,index) => (
            <Row key={index} items={items} />
          ))}
        </tbody>
      </table>
    </div>
  );
};
ReactDOM.render(<App />,document.getElementById('root'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.4/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.4/umd/react-dom.production.min.js"></script>
<div id="root"></div>