Re-rendering이란 어떠한 값의 상태 변화가 일어났을 때, 일어나는 것을 Re-rendering이라고 한다.
결론 : Re-rendering 되는 경우
- props의 변화가 일어났을 때
- state의 변화가 일어났을 때
- 부모 Component 의 state 변화가 일어났을 때
- Redux store 의 변화가 일어났을 때 (아래에 예시가 존재하지 않음)
Components가 Re-rendering 되는지에 대해서 확인을 하려면 React Developer Tools를 활용하여 개발자 도구에서 확인할 수 있다. 해당 도구를 통해서 위의 Re-rendering 되는 경우를 확인해볼 것이다.
예시 코드는 아래와 같다.
Parents Component
GoodChild Component
TroubleChild Component
Parents Component가 mount가 되었을 때 Parents Component에 선언된 state를 3초 뒤에 setter를 통해서 상태를 변경 시켜준다.
또한 Children Component들에게 props를 넘겨주고 있는 상태이다.
props로 받은 text가 div element 안에 들어가 있는 Component다.
props로 받은 onClickProps가 onClick handler로 할당된 30개의 div element 요소를 만들어내는 Component다.
React Developer Tools의 Profiler로 확인해본 결과 아래와 같다.
결과
Parents Component의 state 변화가 일어나자
두 개의 Children Component들 또한 Re-rendering 된 것을 확인할 수 있다.
라는 생각이 들어서 props를 없애버렸다.
Parents Component
GoodChild Component
TroubleChild Component
props에 관련된 내용들은 모두 없애고, React Developer Tools의 Profiler로 확인해본 결과 아래와 같다.
props를 제거한 결과
props에 관련된 내용을 지우고 props를 넘겨주지 않지만,
Children Component들은 Re-rendering이 일어나는 것을 확인할 수 있었다.
일어나지 않게 하는 거는 없을 거 같고 최소화 시킬 수 있는 방법은 있다고 한다.
그래서 위 memoization hook들을 적용시키게 된다면 아래와 같은 코드가 된다.
Parents Component
- Children Component들 같은 경우에는 첫번째로 보여드렸던 코드 예시와 같습니다.
memoization 관련 훅을 모두 적용해준 후,
Parents Component에서 state의 변화를 발생시킨 결과를 React Developer Tools의 Profiler로 확인해본 결과 아래와 같다.
결과
memoization이 가능하다는 useMemo와 useCallback을 적용 시켰는데도 Re-rendering이 일어나는 것을 확인할 수 있다.
이정도면 Re-rendering 그냥 못 막는 거 아닌가 싶은데....
그래서 React의 동작원리를 잠깐 살펴봐보자. 단계가 두가지가 있다.
1. Render Phase
- Component를 호출하여 새로운 Virtual DOM을 반환한다.
- initial rendering이 아니라면 재조정(Reconciliation) 과정을 거친다.
- 재조정(Reconciliation) : 이전 Virtual DOM과 현재 Virtual DOM을 비교하는 것.2. Commit Phase
- Render Phase에서 확인해둔 변경 사항들을 Real DOM과 합성시킨다.
변경 사항들이 없다면 Commit Phase는 건너 뛴다.
즉, memoization hook을 활용해서 Commit Phase는 건너 뛰었다.
하지만 memoization hook을 활용해도 Render Phase는 건너 뛸 수 없다.
Render Phase를 건너 뛰기 위해서는 아래의 키워드를 사용해주면 된다.
React.memo는 전달 받은 props가 이전과 같으면 Component를 Re-rendering 하지 않는다.
그렇다면 이제 Children Component들에게 React.memo를 적용 시켜보겠다.
- Parents Components는 위 첫번째 예시와 같습니다.
GoodChild Component
TroubleChild Component
memoization hook 그리고 React.memo 까지 모두 적용해준 후,
Parents Component에서 state의 변화를 발생시킨 결과를 React Developer Tools의 Profiler로 확인해본 결과 아래와 같다.
결과
위 결과를 마지막으로 useMemo, useCallback을 활용해도 Re-rendering은 일어난다는 것을 알았다.
React.memo를 통해서 완전하게 Re-rendering을 방지할 순 없지만, 최소화 시킬 수 있다는 것도 알았다.
현업자분들의 얘기나 여러 자료들을 확인해보면, React 에서 제공해주는 memoization 함수를 통해서 Re-rendering을 방지하고 좋은 기능을 하는 것은 많지만, 그렇다고 무분별하게 모든 Components에 사용을 하게 되면 오히려 더 서비스의 성능이 악화될 수도 있다고 한다.
뭐든 간에 과유불급이라고 적재적소에 활용하는 것이 매우 좋다고 생각한다.
👏👏👏👏