Skip to content
Advertisement

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

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.

Advertisement

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

Advertisement