如何在使用大量子元素更改元素位置时提高React性能



我有一个带有鼠标移动事件的div来更改位置(topleft(,但div有很多子元素。

当子元素计数小于1000时,效果看起来不错,但当计数超过5000时,效果会变差。

我可以做些什么来提高移动效果性能(我需要显示所有子元素(。

下面是我的示例代码,您可以更改const SPAN_COUNT = 5000来尝试不同数量的子元素。顺便说一句,如果我用纯HTML编码,的性能看起来会更好

https://codesandbox.io/s/cranky-moon-eid68?file=/src/App.js

如果您正在移动的组件每次移动时都不需要更新(迭代并创建5000个组件(,您可以使用React.memo,这将使函数组件的行为类似于使用shouldComponentUpdate浅层比较的类组件。

import React from "react";
import "./styles.css";
import { useState } from "react";
const SPAN_COUNT = 5000;
var spans = Array.from(Array(SPAN_COUNT).keys());
export default function App() {
  const [moving, setMoving] = useState(false);
  const [layerDefaultPosition, setLayerDefaultPosition] = useState();
  const [moveObjectStyle, setMoveObjectStyle] = useState({
    position: "relative",
    top: "0px",
    left: "0px"
  });
  const handleLayerMouseDown = e => {
    setMoving(true);
    const { left, top } = moveObjectStyle;
    setLayerDefaultPosition({
      x: Number(left.split("px")[0]) - e.pageX,
      y: Number(top.split("px")[0]) - e.pageY
    });
  };
  const handleLayerMouseUp = () => {
    setMoving(false);
  };
  const handleLayerMouseMove = e => {
    if (!moving) {
      return;
    }
    const dx = e.pageX + layerDefaultPosition.x;
    const dy = e.pageY + layerDefaultPosition.y;
    const left = `${dx}px`;
    const top = `${dy}px`;
    setMoveObjectStyle({ ...moveObjectStyle, left, top });
  };
  return (
    <div
      className="App"
      style={{ position: "relative", overflow: "hidden", height: "100vh" }}
    >
      <div
        style={moveObjectStyle}
        onMouseDown={handleLayerMouseDown}
        onMouseUp={handleLayerMouseUp}
        onMouseMove={handleLayerMouseMove}
      >
        <MemoSpans spans={spans} />
      </div>
    </div>
  );
}
const Spans = ({spans}) => {
  return (
    <div
      style={{ width: "600px", height: "500px", backgroundColor: "red" }}
    >
      {spans.map(x => (
        <span style={{ display: "inline-block", fontSize: "5px" }}>a</span>
      ))}
    </div>
  )
};
const MemoSpans = React.memo(Spans);

这将停止每次移动正方形时重新创建5000个元素,并且仅在跨距特性更改时重新创建它们(浅比较(。

最新更新