javascript 如何在更改具有批次子元素的元素位置时提高React性能

4ioopgfo  于 2023-01-07  发布在  Java
关注(0)|答案(1)|浏览(84)

我有一个带有鼠标移动事件的div来改变位置(topleft),但是div有很多子元素。
当子元素的数量少于1000时,效果看起来不错,但当数量超过5000时,效果就变差了。
我可以做些什么来提高移动效果的性能(我需要显示所有的子元素)。
下面是我的示例代码,您可以更改const SPAN_COUNT = 5000来尝试不同的子元素计数。顺便说一句,如果我用纯HTML编写此代码,性能看起来会更好
https://codesandbox.io/s/cranky-moon-eid68?file=/src/App.js

rqqzpn5f

rqqzpn5f1#

如果你正在移动的组件不需要在每次移动时更新(迭代并创建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个元素,并且仅在span属性更改时重新创建它们(浅比较)。

相关问题