
지난 글에서는 createElement() 메서드를 직접 구현해보며 JSX 를 ReactElement라는 객체로 변환하는 과정을 학습했다. ReactElement는 화면에 그릴 UI 컴포넌트의 정보를 담고있는 객체라고 배웠는데,
이번에는 그 객체가 DOM 요소로 변환되어 화면에 나타나기까지의 과정에 대해 자세히 학습하며
render() 함수를 직접 구현하는 실습을 해보았다.
그동안 나는 렌더링에 대해서 막연하게 화면에 그려지는거라고 두루뭉술하게 알고 있었다.
이번에 새로 알게된 중요한 사실은, 렌더링이 DOM을 그리는 과정이 아니라는 것이다.
렌더링은 모든 컴포넌트에게 현재 state와 props값의 조합을 기반으로 각각의 UI를 어떻게 화면에 띄우고 싶어 하는지 물어보는 React의 프로세스입니다. - Mark Erikson (Redux Maintainer)
렌더링 과정에서는 컴포넌트를 실행하여 JSX를 반환하고, ReactElement를 생성한다.
이때 React는 변경이 필요해보이는 컴포넌트를 찾아 ReactElement를 확인한다.
렌더링은 이러한 단계들을 거쳐 UI의 구성을 결정하는 과정 이라고 볼 수 있다.

React 공식 문서를 보면 렌더링 과정에 대한 재미있는 비유가 나와있다.
React라는 웨이터가 사용자의 요청을 받아 주방에서 요리를 준비하고, UI를 서빙하는데
아래의 세 단계를 거쳐 UI가 제공된다.
1. 렌더링 Trigger (손님의 주문을 주방으로 전달)
React가 렌더링을 시작할 조건을 감지한다. (ex. state 업데이트, props 변경 등)
상태(state) 변화가 발생한 컴포넌트와 모든 자식 컴포넌트들이 렌더링 대상이 된다.
2. 컴포넌트 Render (주방에서 주문 준비하기)
state가 변경된 컴포넌트로부터 재귀적으로 자식 컴포넌트를 돌며 확인하는 식으로 진행된다.
컴포넌트를 실행하여 JSX를 반환받고 이를 ReactElement 객체로 변환한 다음,
ReactElement를 기반으로 변경이 필요한 컴포넌트를 모아 계산한다.
이 단계에서 새로운 Virtual DOM을 생성한다.
3. DOM에 Commit (테이블에 주문한 요리 서빙)
Virtual DOM의 비교(diffing)를 통해 찾은 변경점들을 업데이트하고, 최종적으로 실제 DOM에 적용한다.
이 단계에서 브라우저 화면이 업데이트된다.

(React가 변경된 부분에 대해서만 선택적으로 DOM을 업데이트하는 모습)
DOM을 업데이트하기 위해 렌더링을 Trigger 하는 조건들은 아래와 같다.
그럼 이렇게 렌더링이 Trigger 된 후, Render 단계에서는 변경이 필요한 부분들을 어떻게 찾아내는건가?
Virtual DOM은 ReactElement를 기반으로 만들어진 트리 구조의 가상 DOM 객체 이다.
렌더링의 Render 단계에서 React는 이전 Virtual DOM과 새로운 Virtual DOM을 비교(diffing)해
변경된 부분만 찾아서 DOM에 업데이트하는데,
여기서 트리끼리 비교하며 변경점을 파악하는 과정을 재조정(Reconcilation) 이라고 한다.
"재조정은 React에서 어떤 부분이 변해야 하는지 두 개의 트리를 비교하는 알고리즘이다."
— Andrew Clark (React Core 팀)
React는 UI 업데이트 시, 이전과 현재의 UI 구조(트리)를 비교하여 변경된 부분만 찾아내는 과정을 거친다.
이때 사용되는 알고리즘이 Reconciliation(재조정)이다.
트리 구조를 비교하는 것은 시간 복잡도가 높은 연산이다. 모든 노드를 비교하는 경우 O(n^2)의 시간복잡도가 발생하는데, React는 휴리스틱(Heuristic) 알고리즘을 적용하여 이를 O(n)으로 최적화했다.
(휴리스틱이란, 완벽한 최적해를 찾기보다 빠르고 현실적인 근사해를 찾는 방법으로,
시간을 절약하고 계산량을 줄이기 위해 일부 연산을 생략하거나, 가능성이 낮은 경로를 미리 배제한다.)
React는 UI 업데이트 시 모든 요소를 비교하는 대신, 다음과 같은 몇가지 규칙을 적용하여 비교 대상을 줄인다.
다른 타입의 요소는 비교하지 않는다.
같은 타입의 요소는 속성만 비교하여 업데이트한다.
리스트 (key 속성) 비교 최적화