react를 다루는 기술

11. 컴포넌트 성능 최적화

crab. 2022. 6. 13. 07:26

많은 데이터 렌더링하기

function createBulkTodos() {
const array = [];
for (let i = 0; i <= 2500; i++) {
    array.push({
    id: i,
    text: `할 일 ${i}`,
    checked: false,
    });
}
return array;
}
  • 성능을 분석해야 할 때는 느려졌다는 느낌만으로 충분하지 않습니다.
  • 정확히 몇 초가 걸리는지 확인해야 하는데, 크롬 개발자 도구의 Performance  탭을 사용하여 측정하면 됩니다.
  • 크롬 개발자 도구의 Performance  탭을 열면 녹화 버튼이 나타납니다.

느려지는 원인 분석

컴포넌트는 다음과 같은 상황에서 리렌더링이 발생합니다.

1. 자신이 전달받은 props가 변경될 때

2. 자신의 state가 바뀔 때

3. 부모 컴포넌트가 리렌더링될 때

4. forceUpdate 함수가 실행될 때

컴포넌트 성능 최적화

  • React.memo라는 함수를 사용합니다.
  • 컴포넌트의 props가 바뀌지 않았다면, 리렌더링하지 않도록 설정하여 함수형 컴포넌트의 리렌더링 성능을 최적화해 줄 수 있습니다.
  • React.memo의 사용법은 매우 간단합니다.
  • 컴포넌트를 만들고 나서 감싸 주기만 하면 됩니다.

useState의 함수형 업데이트

  • setTodos 함수를 사용할 때는 새로운 상태를 파라미터로 넣어 주었습니다.
  • setTodos를 사용할 때 새로운 상태를 파라미터로 넣는 대신, 상태 업데이트를 어떻게 할지 정의해 주는 업데이트 함수를 넣을 수도 있습니다.
  • 이를 함수형 업데이트라고 부릅니다.
  • 일반 setTodos
  • const onInsert = useCallback( (text) => { const nextTodo = { id: nextId.current, text, checked: false, }; setTodos([...todos, nextTodo]); nextId.current += 1; }, [todos], );
  • 함수형 업데이트 사용한 setTodos
    • 두 번째 인자에 관심사를 빼도 된다.
    • useCallback 으로 재사용하도록 만들었지만, 결국 todos를 지켜보아야하는 건 같기 때문에 todos가 변할 때마다 함수가 새로 생성된다.
    • 이걸 지우고 setTodos에서 화살표 함수로 업데이트를 어떻게 할 건지에 대한 업데이트 함수를 만들면 함수를 새로 생성하지 않고 재사용 가능하다.
  • setTodos((todos) => { return [...todos, nextTodo]; }); nextId.current += 1; }, []);

불변성의 중요성

  • 불변성을 지킨다 : 기존의 값을 직접 수정하지 않으면서 새로운 값을 만들어 내는 것
  • 불변성이 지켜지지 않는다면 객체 내부의 값이 수정되어도 변화를 알아차리지 못함
  • React.memo()에서 서로 비교하여 최적화하는 것이 불가능

react-virtualized를 사용한 렌더링 최적화

  • 화면에 보이는 만큼만 렌더링하기.
  • 처음 2500개 모두를 렌더링 하는게 아닌 최대로 보여줄 수 있는 만큼의 개수만 렌더링.
  • 처음 웹 페이지 생성에 속도 굉장히 빨라짐
  • 1. react-virtualized
  • 스크롤되기 전에 보이지 않는 컴포넌트들 렌더링하지 않고 크기만 차지하게끔 한다.
  • 스크롤되면 해당 스크롤 위치에서 보여 주어야 할 컴포넌트 자연스럽게 렌더링
  • 설치 : yarn add react-virtualized
  • 2. 최적화 준비
  • 각 항목의 실제 px 크기 알아내기
  • 크롬 개발 도구로 알아내기
  • 3. TodoList 컴포넌트 수정
  • import {List} from 'react-virtualized';
  • List 컴포넌트: 해당 리스트의 전체 크기(width, height, 전체 개수)각 항목의 높이각 항목을 렌더링할 때 사용하는 함수배열을, 을 props로 넣어야한다.