JSX를 반환할때에는 인접한 요소의 JSX요소들을 반환하지 못합니다. 즉, 하나의 루트로 묶어서 반환해야합니다.
왜냐하면 위 코드에서 JSX는 React.createElement
를 사용하기위한 슈거문법 입니다. 즉, 해당 코드를 보다 편하게 작성하기위한 조치일 뿐 이기 때문에 위 코드는 아래코드로 변환됩니다. 이 문법은 리액트가 VitualDOM
이라는 기술을 이용하기 때문에 한가지의 요소로 묶어서 반환해야 합니다.
이때 이 요소는 JSX요소일 필요가 없습니다. 그냥 하나의 루트로 반환되기만 하면 됩니다. 실제로 아래와 같이 리액트 컴포넌트가 아닌 화살표 함수로 Wrapper로 만들어서 컴포넌트 반환 요소들을 감싸 루트로 반환해도 아무런 오류가 일어나지 않습니다. 하지만 리액트에서는 이트릭을 대체할 좋은 수단인
Fragment
존재합니다.
React는 VirtualDOM
이라는 기술을 이용합니다. VirtualDOM
은 DOM 조작이 발생하면 생기는 여파를 최대한으로 줄여줍니다. 리렌더링시 생기는 계산과정을 줄여줌으로서 렌더링과정을 단축시켜줍니다.
이 VitualDOM
을 간단하게 이야기 하자면 DOM 조작이 발생했을때 실제로 DOM 구조를 변경시키기전에 VitualDOM 안에서 계산해보고 재조정이 필요한지 판단한다음 실제 DOM에 반영하는 과정입니다. 이러한 과정을 보자면 개발자는 VirtualDOM
을 사용하지 않으면 DOM을 조작할 때 마다 이 DOM이 재조정이 필요한가? 라는 의문을 갖고 조작을 해야하는데 VirtualDOM
을 사용함으로서 그러한 계산과정을 자동화 해줍니다.
VirtualDOM
은 아래의 과정을 통해서 리렌더링 여부를 판단합니다.
여기서 우리는 왜 JSX를 쓸때 하나의 루트로 묶어서 반환해야하는지 알 수 있습니다. 인접한 노드를 반환하면 위와 같은 버추얼 돔 트리를 만들 수가 없고 버추얼돔을 통한 최적화 과정을 진행할 수 없기 때문입니다.
Virtual DOM
기존의 DOM 조작을 했을시 발생하는 렌더링 과정을 살펴봅시다.
1. DOM 트리 생성 : 브라우저가 HTML 파일을 전달받으면 해당파일을 파싱해서 DOM 노드로 이루어진 트리를 만듭니다. 각 노드들은 HTML 엘리먼트들과 연관이 있습니다.
2. 렌더 트리 생성 : 외부 css파일과 더불어 각 HTML의 인라인 css 요소를 파싱해서 DOM트리를 기반으로 새로운 렌더트리를 생성합니다. 이 렌더트리를 생성할 때 각 DOM 요소에 attach 라는 메소드가 일을 합니다. 이 메소드는 각 DOM 요소의 스타일 정보를 계산해서 객체로 반환하게 되는데 DOM 트리에 새로운 요소가 들어가면 해당 DOM 요소의 attach 메소드가 실행됩니다.
3. Layout : 각 노드들의 스크린 좌표가 결정되고 어떻게 위치해야하는지 결정됩니다.
- Paint : 트리의 각노드들을 거쳐가면서 paint() 메소드를 실행합니다. 각 DOM요소들에 색을 입히는 과정입니다. 이렇게 스크린에 정보가 표현됩니다.
DOM의 렌더링과정은 충분히 빠릅니다. 하지만 이러한 과정이 쓸데 없이 반복된다면 느려질 수밖에 없습니다. 복잡한 SPA에서는 DOM조작이 빈번하게 발생합니다. 이런 빈번한 DOM조작은 위와 같은 과정들을 거치며 전체적인 프로세스가 비효율적으로 만들어지게 됩니다. 'VirtualDOM'은 이과정에서 빛을 발합니다. 만약 View에 변화가 생긴다면 실제돔에 적용시켜보기전에 VirtualDOM에 먼저 적용시켜보고 최종적인 결과물을 실제 DOM으로 던져줍니다. 이러한 과정에서 브라우저에서 발생하는 연산량이 줄어들어 성능이 개선되게 됩니다.