React-konva slow drag performance with large number of lines rendered

Tags: , , ,



I have problem with dragging functionality while having large number of rendered lines in React-konva.

Currently I am mapping over Array.apply(null, Array(10000)) to render lines horizontally. However, it is very laggy comparing to dragging over an array of only 500 lines for example.

I have prepared codesandbox to illustrate this issue: https://codesandbox.io/s/dazzling-hooks-0xc4s?file=/src/App.js

(Drag mouse horizontally to see the effect)

Any ideas how to solve this issue will be very appreciated.

Answer

Well, you just have too many shapes. The browser is doing a lot of work, rendering them all. There are many ways to improve Konva performance.

The first approach is to just not render objects that are out of visible viewport:

export default function App() {
  const [camera, setCamera] = React.useState({ x: 0, y: 0 });

  const handleDragEnd = (e) => {
    setCamera({
      x: -e.target.x(),
      y: -e.target.y()
    });
  };
  return (
    <div>
      <Stage
        width={window.innerWidth}
        height={500}
        draggable
        onDragEnd={handleDragEnd}
      >
        <Layer>
          {Array.apply(null, Array(10000)).map((_, i) => {
            const x = i * 30;
            const isOut =
              x < camera.x - window.innerWidth ||
              x > camera.x + window.innerWidth * 2;
            if (isOut) {
              return null;
            }
            return (
              <>
                <Line
                  perfectDrawEnabled={false}
                  x={i * 30}
                  y={50}
                  points={[0, 600, 0, 0, 0, 0, 0, 0]}
                  stroke="black"
                />
                <Text
                  x={i * 30}
                  perfectDrawEnabled={false}
                  y={30}
                  text={i.toString()}
                  fill="black"
                />
              </>
            );
          })}
        </Layer>
      </Stage>
    </div>
  );
}

Demo: https://codesandbox.io/s/react-konva-simple-windowing-render-10000-lines-2hy2u



Source: stackoverflow