React Profiler를 사용하여 성능 측정하기. Profiler 도구를 사용하여 React 성능을 측정하고, 어떻게… | by Jeongsk | 원티드랩 기술 블로그 | Medium

notion imagenotion image
Profiler 도구를 사용하여 React 성능을 측정하고, 어떻게 하면 성능을 높일 수 있는지 알아보겠습니다.

React Developer Tools 익스텐션 설치하기

크롬 브라우저에서 Profiler 기능을 이용하기 위해서 React Developer Tools 익스텐션을 설치합니다.
notion imagenotion image

Profiler로 성능 측정하기

React 컴포넌트 성능을 측정하기 위해서, 비교 가능한 2개의 컴포넌트를 만들어보겠습니다. 우리는 두 컴포넌트의 성능 차이를 쉽게 비교하기 위해서 다음과 같은 컴포넌트 2개를 생성합니다.
PhotoOne 컴포넌트는 하위 컴포넌트를 사용하지 않고 하나의 컴포넌트에서 모든 데이터를 렌더링하도록 구현합니다. 그다음 PhotoTwo 컴포넌트는 하위 컴포넌트를 적절하게 분리하여 각각의 하위 컴포넌트에서 데이터를 렌더링하도록 구현합니다.
그리고 두 컴포넌트를 비교하기 위해서 App 컴포넌트에서는 두 컴포넌트를 나란히 렌더링합니다.
이제 렌더링 성능을 측정하기 위해 화면에 출력할 많은 데이터가 필요합니다. 코드에 dummy 데이터를 직접 하드 코딩하여 사용할 수도 있습니다. 하지만 우리는 간단하게 무료로 제공하는 Open API를 사용하여 데이터를 가져와서 화면에 출력해보겠습니다.
다음과 같이 jsonplaceholder 서비스를 이용하여 Photo 데이터를 불러옵니다. Photo 데이터는 5천 건이므로 성능을 측정하기에 충분합니다.
React.useEffect(() => { fetch("https://jsonplaceholder.typicode.com/photos") .then(response => response.json()) .then(setPhotos); }, [setPhotos]);
지금까지 구현한 App.js의 전체 코드는 다음과 같습니다.
이제 React 앱을 실행하고 성능을 측정해보겠습니다. 크롬 개발자 도구를 열어서 Profiler 탭으로 이동합니다.
notion imagenotion image
Profiler 탭을 열어보면 위와 같이 빈화면으로 시작합니다. 성능 데이터를 기록하고 측정하기 위해서 우리는 프로파일링을 수행해야합니다.
레코드 버튼을 클릭하여 프로파일링을 시작합니다. 이제 Profiler는 컴포넌트가 재렌더링이 될 때마다 성능을 기록합니다. 프로파일링을 끝내기 위해서 다시 중지 버튼을 클릭합니다.
프로파일링이 끝나면 다음과 같이 성능 데이터가 나타납니다. 혹시 Profiler의 기능에 대해서 더 궁금하거나, 자세하게 알고 싶으면 Reading performance data 문서를 참고하세요.
notion imagenotion image
위의 Flamegraph 차트를 보면 App 컴포넌트는 렌더링하는데 191.3ms가 걸렸습니다. 그리고 PhotoOne 컴포넌트는 73.5ms가 걸렸고, PhotoTwo 컴포넌트는 116.6ms가 걸렸습니다. PhotoOne 보다 PhotoTwo 컴포넌트의 렌더링 시간이 더 오래 걸렸다는 것을 알 수 있습니다.
notion imagenotion image
그리고 Ranked 차트를 살펴보면, PhotoOne 컴포넌트의 렌더링 시간이 제일 오래걸렸다는 것도 알 수 있습니다. 여기까지만 보았을 때는 PhotoOne 컴포넌트의 성능이 더 좋아 보입니다.

React.memo를 사용하여 성능 최적화하기

이제 컴포넌트 성능을 최적화 해보겠습니다.
React Developer Tools 설정 버튼(톱니바퀴 아이콘)을 클릭합니다. 그리고 Highlight updates when compoennts render 옵션을 켜줍니다. 이 옵션은 렌더링이 발생하는 컴포넌트를 브라우저 화면에 표시해줍니다.
notion imagenotion image
아래 GIF 이미지로 캡쳐한 화면을 보면 message 데이터가 변할 때마다 모든 컴포넌트의 렌더링이 발생하는 것을 알 수 있습니다.
notion imagenotion image
메세지를 입력할 때마다, Message 컴포넌트만 재렌더링하면 되는데, 전체 컴포넌트가 재렌더링되고 있습니다. 우리는 어떤 부분이 성능 저하를 일으키는 원인인지 알 수 있습니다.
이제 컴포넌트의 렌더링 성능 최적화를 해줄 수 있는 React.memo 기능을 사용해보겠습니다. 다음과 같이 PhotoOne과 PhotoTwo 컴포넌트를 수정하여 리렌더링을 방지합니다.
그리고나서 Profiler에서 성능을 다시 측정합니다.
notion imagenotion image
이제 App 컴포넌트는 렌더링하는데 59ms가 걸렸습니다. 이전보다 3배 이상 빨라졌습니다. 그리고 PhotoOne 컴포넌트는 59ms, PhotoTwo는 0.1ms가 걸렸습니다. 이전보다 PhotoTwo의 렌더링 속도가 매우 빨라진 것을 알수 있습니다.
PhotoTwo의 렌더링 속도가 빨라진 이유는 Ranked 차트를 보면 더 자세하게 알 수 있습니다. PhotoOne는 전체 컴포넌트를 재렌더링했지만, PhotoTwo는 Message 컴포넌트만 재렌더링했기 때문에 성능이 매우 좋아졌습니다.
notion imagenotion image

글을 마치며…

렌더링 성능을 최적화 하기 위해서 React 컴포넌트를 분리하고, React.memo를 사용하면 성능이 향상된다는 것을 알 수 있었습니다.
참고로 React API 문서에는 React.memo가 props를 비교할때 shallow 비교를 수행한다고 나와있습니다. 하지만 React.memo를 리렌더링 방지에 사용하면 버그를 유발할 수 있으며, 성능 최적화에만 사용하는 것을 권장하고 있습니다. 그러므로 React.memo를 사용하여 성능을 최적화 할때는 Profiling을 꼭 사용하시길 바랍니다.
React 성능을 최적화하기 위한 다른 방법들도 존재합니다. 하지만 이 글에서 소개한 2가지 방법만 사용해도 매우 좋은 결과를 얻을 수 있었습니다. 성능 최적화에 대한 다른 방법도 궁금하다면 Optimizing Performance 문서를 읽어보세요.