브라우저 렌더링

리액트에서 렌더링 === 함수를 호출하는 것
예시코드: 불필요한 렌더링을 막아보자!

- FirstChild: state
- SecondChild: props
리렌더링 조건
- state가 바뀌었을 때
- props가 바뀌었을 때

💡 참조값이 달라졌다?
- Parent 컴포넌트가 리렌더링될 때마다 handleClick 함수가 매번 재생성이 됨
- 함수가 ‘참조’ 타입의 데이터이기 때문!
🤔 그렇다면 참조값이 바뀌지 않도록 해주면, secondChild의 불필요한 리렌더링을 방지해줄 수 있지 않을까?
시도 1️⃣ 함수를 메모이제이션?
useCallback : 함수를 메모이제이션
- 메모이제이션?
- 기존에 수행한 연산의 결괏값을 어딘가에 저장해두고 필요할 때 재사용하는 기법
- 의존성 배열이 바뀌지 않는 이상, 컴포넌트가 리렌더링 될 때마다 변수에 같은 함수가 할당됨

✅ 리액트에서의 렌더링 - Render Phase → Commit Phase


🤔 useCallback으로 불필요한 렌더링을 막을 수는 없었지만?
그래도 렌더링 최적화 효과는 있음!

시도 2️⃣ render phase까지 막아볼 순 없을까? (React.memo)
React.memo
- 전달받은 props가 이전 props와 비교했을 때 같으면, 컴포넌트의 리렌더링을 막아줌
- 마지막으로 렌더링된 결과를 재사용하는 고차 컴포넌트
- props 비교 시, 기본적으로
얕은 비교를 통해서 진행!
-
원시 타입의 데이터인 경우, 값이 다른지 비교!
-
참조 타입의 데이터인 경우, 참조값이 같은지를 비교!
-
비교 함수를 넣어서 비교 가능

props인 onClick을 비교!
시도 3️⃣ 객체를 props로 넘겨주게 된다면? (useMemo)


🤔 useMemo
- 함수에 대한 메모이제이션을 제공하는 useCallback과는 다르게,
값에 대한 메모이제이션을 제공!
- 의존성 배열에 들어있는 값이 변경되지 않는 이상, 매번 리렌더링 될 때마다 같은 값을 반환

결론
1. useCallback, React.memo, useMemo를 이용해 리액트 렌더링 성능 향상 가능
🤔 무작정 사용해도 좋을까?
- 결국은 모두 비용..
- 어떤 곳에 적용해야 최적화할 수 있는건지 고민해볼 필요가 있음
2. 최적화 도구를 사용하기 전에, 불필요한 렌더링이 발생하지 않도록 근본적으로 설계하자
3. 어떻게 코드를 개선할까?

- 기존에는 위 코드처럼 부모 컴포넌트 내부에서 Consoler 컴포넌트를 사용함

- children을 사용해서 Consoler 컴포넌트를 주입
- 오른쪽 코드는 바벨로 컴파일된 코드
- Consoler 컴포넌트의 React.createElement가 존재하지 않기 때문에 부모 컴포넌트가 호출되더라도 Consoler 컴포넌트는 호출되지 않음
4. 성급한 최적화는 금물!
출처
https://www.youtube.com/watch?v=1YAWshEGU6g