렌더링 작업은 때때로 리소스를 낭비하게 될 수 있습니다. 만약 컴포넌트의 렌더링 결과가 이전 DOM과 다르지 않다면 해당 컴포넌트를 렌더링하는 것은 시간, 자원의 낭비에 불과합니다.

Reconciliation

글을 요약하면, react는 두 렌더링 트리를 root부터 쭉 재귀적으로 비교하게 된다. 이 때 알고리즘은 렌더링 여부 결정과정에서 element의 타입이 바뀌었는가(1) 와 key의 변경이 있는가 (2)를 확인합니다.

1. type diff

엘리먼트 또는 컴포넌트의 타입이 다른 경우, 예를 들어 <div>...</div><section>...</section> 로 바뀌는 경우에는 해당 트리 노드와 그 아랫부분은 완전히 버려지고 새로 만들어집니다. 이 때 이전 트리와 연결된 모든 state 또한 사라집니다.

따라서 불필요한 렌더링을 막으려면 같은 타입의 컴포넌트 인스턴스가 새로 생기는 것을 방지해야 합니다. 이 예시는 다음과 같습니다.

const Parent = () => {
	const Child = () => <div>My type changes every render</div>
	return <Child/>
}

위 는 렌더링될 때마다 새로운 컴포넌트의 인스턴스를 생성하기 때문에, Child와 그 자식 컴포넌트들은 파괴되었다가 재생성됩니다.

이를 방지하려면 다음과 같이 Child를 외부에 정의해야 합니다. (또는 useMemo를 사용해야 한다.)

const Child = () => <div>My type is now immutable</div>

const Parent = () => {
	return <Child />
}

2. key diff

DOM 노드들의 자식들을 재귀적으로 비교할 때, react는 두 리스트를 돌면서 서로 차이점이 있을 때 변경을 결정합니다. 아래 코드들은 react 문서에서 가져온 것들입니다.

// prev DOM
<ul>
  <li>first</li>
  <li>second</li>
</ul>
// next DOM
<ul>
  <li>first</li>
  <li>second</li>
  <li>third</li>
</ul>