실시간 암호화폐 데이터를 이용한 프로젝트다 보니 렌더링이 자주 발생해 성능 저하를 고려했다. 성능 저하의 원인을 분석하기 위해 먼저 개발 도구의 Lighthouse를 이용해 성능을 측정했고 Performance 점수가 26으로 매우 낮게 나왔다.
실시간 데이터를 렌더링할 때 매번 전체 데이터를 다시 렌더링하는 방식을 사용했지만 데이터 양이 많아질수록 성능이 저하되는 문제 발생했다.


중점적으로 담당했던 암호화폐의 실시간 현재가, 거래액 등을 볼 수 있는 테이블(표)이 하나의 데이터의 상태값만 변경되어도 테이블 전체가 다시 렌더링되는 문제가 있었다.
Memoization 적용
먼저, 컴포넌트를 작게 나누고 각 컴포넌트에 Memoization 기법을 활용하여 데이터를 캐싱하고, 이전에 렌더링한 결과를 재사용하여 중복 계산을 방지하고 성능을 개선했다.
이를 통해 렌더링 속도를 높이고 사용자 경험을 향상시켰다.
Windowing 적용
빗썸은 약 275개의 암호화폐 목록을 볼 수 있는 테이블이라 스크롤을 해야지만 볼 수 있는 목록까지 렌더링이 이루어지는 것은 비효율적이라 생각이 되었다.
따라서, 이를 개선하기 위해 화면에 표시되는 데이터의 일부만 렌더링하고 스크롤이나 페이지 이동 등의 동작에 따라 동적으로 데이터를 로그하는 기술인 Windowing 기법을 적용했다.
Windowing 기법을 적용하는 과정에서 react-window vs react-virtualized 두 라이브러리를 ****중에 고민했는데 많은 기능이 필요하지 않고 테이블의 높이가 고정적인 나의 프로젝트에서는 react-virtualized에 비해 react-window가 더 가벼워 선택하게 되었다.
이를 통해 매번 전체 데이터를 다시 렌더링할 필요없이 화면에 필요한 부분만 렌더링하여 성능을 향상 시켰다.


import { ListChildComponentProps } from 'react-window';
const CoinList = ({
data: socketData,
index,
style,
}: ListChildComponentProps) => {
...
return (
<styled.CoinBox
id={symbol}
onClick={clickCoinHandler}
$selected={selectedCoin === symbol}
style={style}
>
<CoinInfo coinName={coinName} thumbnail={thumbnail} symbol={symbol} />
<CoinPrice tradePrice={tradePrice} binanceKRWPrice={binanceKRWPrice} />
<CoinKimp
binanceKRWPrice={binanceKRWPrice}
kimpRatio={kimpRatio}
kimpDiff={kimpDiff}
/>
<CoinChange changeRatio={changeRatio} changePrice={changePrice} />
<CoinHighest highestRatio={highestRatio} highestPrice={highestPrice} />
<CoinLowest lowestRatio={lowestRatio} lowestPrice={lowestPrice} />
<TradeValue tradeValue_24H={tradeValue_24H} />
</styled.CoinBox>
);
};
export default memo(CoinList);