리액트는 컴포넌트를 렌더링 할때 가상돔(virtual DOM)을 생성하여 렌더링 하기 때문에 렌더링 과정을 알고, 그에 맞는 최적화 방법을 알아 두는 것이 좋다.
거두절미하고 본론부터 들어가보자.
리액트 *마운트 과정
*마운트(Mount) : 컴포넌트 생성부터 최초 렌더링 까지의 과정
- 함수 컴포넌트 호출
- 구현부 실행
: props 취득, hook 실행, 내부 변수 및 함수 생성
- return 실행
: 렌더링 시작
- Render Phase
: 가상 DOM 생성
- Commit Phase
: 실제 DOM 반영
- useLayoutEffect
: 브라우저가 화면에 Paint 하기 전에, effect가 동기로 실행된다.
- 이때 props, state에 변화가 있다면 재렌더링 된다.
- Paint
: 브라우저가 실제 DOM을 화면에 그린다.
- useEffect
: Mount가 되어 화면에 그려진 후, effect가 비동기로 실행된다.
자, 그럼 리액트 컴포넌트 리렌더링이 일어나는 과정은 어떻게 될까?
과정을 알아보기 전 우선 컴포넌트가 어떤 경우에 리렌더링이 되는지 짚어보고 넘어가자.
컴포넌트 리렌더링 경우
- state의 변화
- props의 변화
- 중앙 상태값(redux store)의 변화
- 부모 컴포넌트가 리렌더링 되는 경우
리액트 컴포넌트 리렌더링 과정
- 함수 컴포넌트 재호출
- 구현부 실행
: props 취득, hook 실행, 내부 변수 및 함수 재생성
- return 실행
: 렌더링 시작
- Render Phase
: 가상 DOM 생성
- Commit Phase
: 실제 DOM 반영
- useLayoutEffect
: 브라우저가 화면에 Paint 하기 전에, effect가 동기로 실행된다.
- 이때 props, state에 변화가 있다면 재렌더링 된다.
- Paint
: 브라우저가 실제 DOM을 화면에 그린다.
- useEffect
: Mount가 되어 화면에 그려진 후, effect가 비동기로 실행된다.
Mount 과정과 비슷하지만 함수 컴포넌트와 내부 변수 및 함수를 재호출하고, 재생성한다는 차이점이 있다.
그렇다면 부모 컴포넌트에서 리렌더링이 일어나는 경우 자식 컴포넌트 중 리렌더링이 필요하지 않은 컴포넌트와 내부 변수/함수 또한 리렌더링이 일어나게 되는 불상사가 발생하게 된다.
불필요한 리렌더링을 막는 방법은 뭐가 있을까?
컴포넌트 리렌더링 최적화
자식 컴포넌트의 불필요한 리렌더링
: 부모 컴포넌트가 리렌더링 되면, 자식 컴포넌트도 모두 리렌더링이 된다.
- React.memo를 사용하여 자신이 전달받는 props가 변경 되었을 때만 리렌더링 하도록 최적화 한다.
내부 변수/ 함수의 불필요한 재생성
: 컴포넌트 리렌더링 시 해당 함수 컴포넌트가 재호출 되면서 내부 변수와 함수의 참조값이 변경되어 새로 생성된다.
- useMemo와 useCallback을 사용하여 최초의 값을 저장한 후 재사용할 수 있도록 최적화 한다.