mingg IT

[React+MUI5] 테이블 렌더링 최적화 본문

FrontEnd

[React+MUI5] 테이블 렌더링 최적화

mingg123 2023. 10. 24. 13:41

현상

 

  • expanded 되는 테이블 형식으로 바꾼 이후부터 렌더링이 눈에 띄게 느려졌다.
  • 필터를 이용하면 테이블을 그려주는 형식이 변하는 동적 테이블 형식이였다.
  • 또한 필터를 선택하면 백엔드로 API를 호출하는 것이아닌, 프론트에서 reduce를 이용해 소계를 다시 계산 하는 등 브라우저에 무리가 될 수도 있는 동작이 포함되어 있었다.

 

 

원인

 

  • 데이터가 많아서 오래걸리는걸까봐 MUI의 virtualized table을 적용해보았지만 여전히 느렸다. 
  • virtualized table을 적용후에도 여전히 느림을 확인한 이후, 이건 데이터를 보여주고 해당 데이터를 계산하는데 오래 걸려서의 문제가 아니라 테이블을 그리기 위해 계산하는 reflow시 발생하는 문제일거라고 추측했다.  
  • virtualized table 은 한번에 모든 데이터를 보여주는 것이아닌 화면에서 보여지는, 스크롤하는 만큼 데이터가 보여지는 것이기 떄문이다

 

 

해결

 

우선 크롬 익스텐션 React Developer Tools를 이용하여 Profile을 확인했다.

BaseTable 컴포넌트에서 매우 오래걸린다고 친절하게 알려준다. 

내부를 클릭해보면 각 리렌더링에 소요되는 시간을 확인할 수 있다. 

 

이제 힌트를 얻었으니 문제가되는 BaseTable.tsx 코드로 가서 확인해보자. 

{variant.type === 'expandable' &&
    expandedRows.map((expandedRow, expandedRowIdx) => (
        <Table.Head.Row
            key={expandedRowIdx}
            sx={{
                visibility: variant.isExpanded(row, rowIdx) ? 'visible' : 'collapse',
            }}>
            <StyledTableHeadRowCell />
            {columns.map((column, colIdx) => (
                <StyledTableBodyRowCell
                    isStickyUnderBreakpoint={column.isStickyUnderBreakpoint}
                    {...column.cellProps}
                    key={colIdx}>
                    <Typography variant='body2'>{expandedRow[column.key]}</Typography>
                </StyledTableBodyRowCell>
            ))}
        </Table.Head.Row>
    ))}

내부를 살펴보면 variant.isExpanded 함수가 Table을 그려주는 내부에 있어서

모든 row를 그려줄때마다 수행되어 reflow가 발생하는 것이다. 

 

 

sx 내부에서 계산을 매번했던 로직을 제거하고 visible, collaps 대신 삼항연산자를 이용했다. 

{variant.type === 'expandable' &&
    expandedRows.map((expandedRow, expandedRowIdx) =>
        variant.isExpanded(row, rowIdx) ? (
            <Table.Head.Row
                key={expandedRowIdx}
               >
                <StyledTableHeadRowCell />
                {columns.map((column, colIdx) => (
                    <StyledTableBodyRowCell
                        isStickyUnderBreakpoint={column.isStickyUnderBreakpoint}
                        {...column.cellProps}
                        key={colIdx}>
                        <Typography variant='body2'>{expandedRow[column.key]}</Typography>
                    </StyledTableBodyRowCell>
                ))}
            </Table.Head.Row>
        ) : null
)}

이로인해 table.head.row 내부에서 계속 수행되던 함수와 수행이후 reflow가 일어나지 않을 것이다. 

 

Profile을 다시 수행해봐도 이전 BaseTable이 오래걸린다는 노란색 표시가 뜨지 않았다. 

 

 

 

 

성능 개선 결과

 

눈으로 보기에도 테이블 렌더링 속도가 빨라짐을 느꼈다. 

왼쪽이 개선하기 전 profile 결과이고, 우측이 개선 후 profile 결과이다. 

개선 전 / 개선 후

profile을 이용하여 렌더링이 오래걸리는 컴포넌트를 찾았고, 어디가 원인일지 추측하여 해결하는 방법에 대해 배웠다.

 

 

 

 

 

 

 

 

 

Comments