0

I am using React 17.0.2 and I have a performance issue related to how I render an array containing a large number of JSX elements (it may vary from 100 to ~650 elements).

In particular, I would like to show, in a scrollable container, a certain number of different "Cards" where each one of them contains a chart, images, icons and paragraphs. These details change everytime the SSE sends new data.

The code below works just fine and does what I was expecting it to do but the rendering is quite slow. The app I am working on should be used on mobiles too and I am afraid that the waiting would be a tad too much for a user to bear.

Contestants:

const Contestants = memo(() => {
  return (
    <div className={`${'contestants-container animate__animated animate__fadeIn'} ${classes.mainContainer}`}>
      <div className={`${'mx-0 my-0'} ${classes.cardsContainer}`}>
        <PerfectScrollbar>
          <div className='d-flex flex-wrap align-items-center justify-content-evenly' >
            <DetailCards />
          </div>
        </PerfectScrollbar>
      </div>
    </div>    
  )
})
export default Contestants

DetailCards

const DetailCards = memo(() => {

 // ** Context
 const fetchDataContext = useContext(FetchDataContext)
 const vehicleData = fetchDataContext.vehicleData
 const locationData = fetchDataContext.locationData
 const payloadSSE = fetchDataContext.payloadSSE

 // ** State
 const [detailCardsArray, setDetailCardsArray] = useState([])
 const [initialLocationFlag, setInitialLocationFlag] = useState(true)
 const [initialLocationData, setInitialLocationData] = useState({})

 const detailCardsArrayRef = useRef(detailCardsArray)
 
 useEffect(() => {
   if (detailCardsArray) {
     detailCardsArrayRef.current = detailCardsArray
   }
 }, [detailCardsArray])

 useEffect(() => {
   setInitialLocationFlag(true)
 }, [])

 useEffect(() => {
   if (initialLocationFlag === true && Object.keys(locationData).length !== 0) {
     setInitialLocationData(locationData)
     setInitialLocationFlag(false)
   }
 }, [locationData, initialLocationFlag])

 useEffect(() => {
   if (Object.keys(vehicleData).length !== 0 && Object.keys(initialLocationData).length !== 0) {
     let temporaryDetailCardsArray = []
     for (let i = 0; i < Object.keys(vehicleData).length; i++) {
       temporaryDetailCardsArray.push(
         <DetailCard 
           key={vehicleData[Object.keys(vehicleData)[i]].imei} 
           object1={vehicleData[Object.keys(vehicleData)[i]]} 
           object2={initialLocationData[Object.keys(vehicleData)[i]]} 
         />
       )
     }
     setDetailCardsArray(temporaryDetailCardsArray)
   }
 }, [vehicleData, initialLocationData])

 useEffect(() => {
   if (detailCardsArrayRef.current.length !== 0) {
     if (typeof payloadSSE !== 'undefined' && payloadSSE !== null) {
       for (let i = 0; i < detailCardsArrayRef.current.length; i++) {
         if (detailCardsArrayRef.current[i].key === payloadSSE.imei) {
           detailCardsArrayRef.current[i] = (
             <DetailCard 
               key={detailCardsArrayRef.current[i].key} 
               object1={detailCardsArrayRef.current[i].props.object1} 
               object2={payloadSSE} 
             />
           )         
         }
       }
     }
     setDetailCardsArray(detailCardsArrayRef.current) 
   }
 }, [payloadSSE])
 
 return detailCardsArray
})

export default DetailCards

So, is there a way to render the array faster? I thought about virtualization but I am unsure about how to implement it.

Thank you!

2

1 Answer 1

1

The problem was solved by using @Piotr Żak suggestion to fetch a certain number of elements and give the user the option to load more. Furthermore, I added pagination as well. Now it works just fine even on mobiles.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.