Correct way to cache Konvajs shape in React for large duplicates shapes

74 views Asked by At

I'm trying to optimise KonvaJS performance. One way is to cache shape. Here i try to draw 1000 times the same shape but with different position. Thanks! This is my code :

export default function AircraftLayer() {
  const { aircrafts } = useAircraft() //1000 objects
  const rectLabelRef = useRef<Konva.Rect>(null)

  useEffect(() => {
    if (rectLabelRef.current) {
      rectLabelRef.current.cache()
    }
  }, [rectLabelRef])

  return (
    <Layer>
      {aircrafts.map((aircraft) => (
        <Rect
          ref={rectLabelRef}
          width={120}
          height={40}
          fill={'red'}
          perfectDrawEnabled={false}
          hitStrokeWidth={0}
          shadowForStrokeEnabled={false}
          x={aircraft.positionX}
          y={aircraft.positionY}
        />
      ))}
    </Layer>
  )
}

I try to use React ref to do it but no result...

1

There are 1 answers

0
lavrton On

First, I don't recommend caching every simple rectangle. It will not boost the performance and may even drop it.

Read here some caching tips: https://konvajs.org/docs/performance/Shape_Caching.html

You cannot use the same ref for several React elements. You will have to isolate every rectangle into its own:

function MyShape({ aircraft }) {
  const rectLabelRef = useRef<Konva.Rect>(null)

  useEffect(() => {
    if (rectLabelRef.current) {
      rectLabelRef.current.cache()
    }
  }, [rectLabelRef])

  return (
        <Rect
          ref={rectLabelRef}
          width={120}
          height={40}
          fill={'red'}
          perfectDrawEnabled={false}
          hitStrokeWidth={0}
          shadowForStrokeEnabled={false}
          x={aircraft.positionX}
          y={aircraft.positionY}
        />
  )
}

export default function AircraftLayer() {
  const { aircrafts } = useAircraft() //1000 objects
 
  return (
    <Layer>
      {aircrafts.map((aircraft) => (
        <MyShape
          aircraft={aircraft}
          key={aircraft.id}
        />
      ))}
    </Layer>
  )
}