본문 바로가기
JavaScript/React

React) 컴포넌트 성능 최적화 - React DevTools, 느려지는 원인 분석

by 박채니 2022. 11. 20.
안녕하세요, 코린이의 코딩 학습기 채니 입니다.
[리액트를 다루는 기술]의 책을 참고하여 포스팅한 개인 공부 내용입니다.

 

컴포넌트 성능 최적화

 

이전에 만들어본 일정 관리 웹 애플리케이션을 기반으로 컴포넌트의 성능을 최적화해보겠습니다.

현재로는 데이터가 적기 때문에 느려지는 것을 체감할 수 없어서 많은 데이터를 렌더링해보겠습니다.

 

 

많은 데이터 렌더링하기

App.js

import { useState, useRef, useCallback } from 'react';
import TodoInsert from "./components/TodoInsert";
import TodoList from "./components/TodoList";
import TodoTemplate from "./components/TodoTemplate";

function createBulkTodos() {
  const array = [];
  for(let i = 1; i <= 2500; i++) {
    array.push({
      id: i,
      text: `할 일 ${i}`,
      checked: false
    });
  }

  return array;
}

const App = () => {
  const [ todos, setTodos ] = useState(createBulkTodos);

  // 고윳값으로 사용될 id
  // ref를 사용해 변수 담기
  const nextId = useRef(2501);

2500개의 객체를 담은 배열을 생성하여 리턴해주는 createBulkTodos 함수를 생성해주었습니다.

이 때 useState의 기본 값에 함수를 넣어주었는데, 만일 useState(createBulkTodos())로 작성하면 리렌더링될 때마다 함수가 호출됩니다.

따라서 처음 렌더링될 때만 함수 호출이 이루어지도록 useState(createBulkTodos)로 작성해주었습니다.

 

하나를 선택하면 이전보다 굉장히 느려진 것을 체감할 수 있습니다.

 


크롬 개발자 도구를 통한 성능 모니터링

React DevTools를 사용하여 기능 수행 시 정확히 몇 초가 걸리는 지 확인해보겠습니다.

리액트 개발자 도구의 Components 탭 우측의 Profiler 탭을 열어 확인할 수 있습니다.

 

좌측 상단에 파란색 녹화 버튼이 보여집니다.

해당 버튼을 누르고 할 일 목록 하나를 체크한 후, 화면이 변화되면 녹화 버튼을 한 번 더 눌러줍니다.

그럼 위와 같이 성능 분석 결과가 나타나게 됩니다.

 

Durations Render → 리렌더링에 소요된 시간

즉, 화면을 변화하는데에 337.9ms가 소요되었다는 것을 알 수 있습니다.

차트 모양을 클릭하면, 리렌더링된 컴포넌트들을 오래 걸린 순으로 정렬하여 나열해줍니다.

쭉 확인해보면, 변화를 일으킨 컴포넌트와 관계가 없는 컴포넌트들까지도 리렌더링된 것을 확인할 수 있습니다.

굉장히 좋지 못한 성능을 지니고 있다고 짐작할 수 있습니다.

 


느려지는 원인 분석

 

컴포넌트는 아래와 같은 상황에서 리렌더링됩니다.

 

  • 자신이 전달받은 props가 변경될 때
  • 자신의 state가 바뀔 때
  • 부모 컴포넌트가 리렌더링될 때
  • forceUpdate 함수가 실행될 때

이를 고려해본다면, '할 일 1' 항목을 체크할 경우

① App 컴포넌트의 state가 변경

② 그로 인해 App 컴포넌트 리렌더링

③ 부모 컴포넌트가 리렌더링 되었으니 TodoList 컴포넌트 리렌더링

④ 그 안의 무수한 컴포넌트들이 리렌더링

 

위 과정을 거치고 있게 되는 것이죠.

'할 일 1' 항목은 업데이트가 되었으니 리렌더링 되어야 하는 것은 맞지만 이 외 할 일 2 ~ 2500은 굳이 리렌더링 될 필요가 없는데 리렌더링이 되어 성능 저하가 일어나는 것입니다.

 

따라서 컴포넌트 리렌더링 성능을 최적화해 주는 작업 (리렌더링이 불필요할 때는 리렌더링 방지)을 해 줘야 합니다.

이는 다음 포스팅에서 작성해보겠습니다!