Frontend

React rendering performance optimization

mechaniccoder 2023. 4. 27. 00:04

React 렌더링 성능 최적화 과정

안녕하세요. 이번 포스팅에서는 실무에서 겪었던 렌더링 성능 이슈와 어떠한 과정을 거쳐서 해결했는지 공유해보도록 하겠습니다.

Issue

문제가 된 이슈에 대해 간략히 설명해보겠습니다. 여러 개의 text를 선택해 tts 요청을 보내고 response가 왔을때 성공했다는 UI를 그리게 위해 state를 업데이트하는 상황입니다. 그러나 여러 개의 text를 가지고 있는 컴포넌트들의 숫자가 굉장히 많아질 경우 리렌더링이 여러번 발생하기 때문에 토스트를 띄운다거나 할때 토스트 애니메이션이 버벅이는 jank 현상이 있었습니다.

Chrome devtools performance tab

먼저 큰 그림에서 어떤 부분이 문제인지를 파악하기 위해 chrome devtools에서 performance tab을 활용했습니다.

아래 이미지에서 하단 heap 메모리 사용량을 보면 특정 시점부터 갑자기 증가하다가 뚝 떨어지는 것을 확인할 수 있습니다. 이때 예상으로는 리렌더링이 엄청나게 일어나다가 garbage collector가 작동한다고 생각했습니다.

main thread를 확인해봐도 엄청나게 많은 수의 콜스택이 있는 것을 확인할 수 있었습니다.

아래 이미지의 왼쪽 빨간 박스를 보면 click 이벤트와 dispatch가 호출되는 것을 확인할 수 있습니다. 이를 통해 리렌더링이 발생했다는 것을 알 수 있죠. 세부적으로 어떤 컴포넌트가 문제인지 파악하기 위해 react profiler devtools를 사용했습니다.

React profiler

다시 한번 해당 동작을 react profiler를 사용해 record했고 아래 이미지의 빨간 박스에서 보다시피 리렌더링 원인을 파악했습니다.

React component devtools에서 해당하는 순서의 hook을 파악하여 수정해야할 코드를 찾을 수 있었습니다.

Result

렌더링 성능 최적화기 전과 후의 비교 동영상입니다. 오른쪽 상단을 확인해보면 최적화하기 전에는 노란색 바가 많은 것을 확인할 수 있습니다. 이는 rendering에 걸린 duration으로 렌더링 비용이 비싸다는 것을 의미합니다.

최적화 전

최적화 후

최적화하기 전에는 평균 150ms 걸린 반면 최적화 후에는 50ms정도로 66% 성능 향상이 됐습니다.

마치며

렌더링 성능 최적화를 하면서 느꼈던 점은 list 컴포넌트는 조심해야 한다는 것을 알게됐습니다. 단순히 별거 아닌 리렌더링도 여러 item을 가지고 있는 list 컴포넌트의 경우 성능이 매우 나빠져 좋지 않은 사용자 경험을 유발합니다.

리팩토링 2판 책에 최적화 관련하여 이런 말이 나옵니다.

첫 번째, 하지마라. 두 번째(전문가 한정) 아직 하지 마라

그렇지만 제가 겪었던 문제의 경우 많은 수의 item들이 있기 때문에 선제적으로 리렌더링이 되지 않도록 예방을 했다면 더 좋지 않았을까 하는 생각도 드네요.