
DOM은 웹페이지에 대한 인터페이스로 브라우저가 웹페이지의 콘텐츠와 구조를 어떻게 보여줄 지에 대한 정보를 담고있다.
앞서 살펴본 것처럼 브라우저가 웹페이지를 렌더링하는 과정은 매우 복잡하고 많은 비용이 든다. 또한 대다수의 앱은 렌더링된 이후, 사용자의 인터랙션을 통해 다양한 정보를 노출하므로 웹페이지가 변경되는 상황도 고려해야 한다.
렌더링 이후 추가 렌더링 작업은 하나의 페이지에서 모든 작업이 일어나는 싱글 페이지 애플리케이션에서 더욱 많아진다. 하나의 페이지에서 계속해서 요소의 위치를 재계산하게 된다. 싱글 페이지 애플리케이션의 특징 덕분에 사용자는 자연스러운 웹페이지 탐색을 할 수 있지만 그만큼 DOM을 관리하는 과정에서 부담해야할 비용이 커진다.
사용자의 인터랙션에 따라 DOM의 모든 변경 사항을 추적하는 것은 개발자 입장에서 너무 수고스러운 일이다. 이러한 문제점을 해결하기 위해 탄생한 것이 바로 가상 DOM이다. 가상 DOM은 말 그대로 실제 브라우저의 DOM이 아닌 리액트가 관리하는 가상의 DOM을 의미한다.
가상 DOM은 웹페이지가 표시해야할 DOM을 일단 메모리에 저장하고 리액트가 실제 변경에 대한 준비가 완료됐을 때 실제 브라우저의 DOM에 반영한다.
DOM 계산을 브라우저가 아닌 메모리에서 계산하는 과정을 한 번 거치게 된다면 실제로는 여러 번 발생했을 렌더링 과정을 최소화할 수 있고 브라우저와 개발자의 부담을 덜 수 있다.
리액트 파이버는 리액트에서 관리하는 평범한 자바스크립트 객체이다. 파이버는 가상 DOM과 실제 DOM을 비교해 변경 사항을 수집하고, 이 둘 사이에 차이가 있으면 화면에 렌더링을 요청하는 역할을 한다.
리액트 파이버의 목표는 리액트 웹 어플리케이션에서 발생하는 사용자 인터랙션에 올바른 결과물을 만드는 반응성 문제를 해결하는 것이다. 이를 위해 파이버는 아래와 같은 일을 할 수 있다
이러한 모든 과정은 비동기로 일어난다.
파이버는 일단 하나의 작업 단위로 구성되어 있다. 리액트는 이러한 작업 단위를 하나씩 처리하고 finishedWork()라는 작업으로 마무리한다. 그리고 이 작업을 커밋해 실제 브라우저 DOM에 가시적인 변경사항을 만들어 낸다.
파이버는 컴포넌트가 최초로 마운트 되는 시점에 생성되며 이후에는 가급적이면 재사용된다.
리액트 파이버 트리는 리액트 내부에서 두 개가 존재한다.
리액트 파이버의 작업이 끝나면 리액트는 단순히 포인터만 변경해 workInProgress 트리를 현재 트리로 바꾸는 더블 버퍼링을 한다.
리액트에서 미처 다 그리지 못한 모습을 노출시키지 않기 위해(불완전한 트리를 보여주지 않기 위해) 더블버퍼링 기법을 사용하며 커밋 단계에서 더블버퍼링이 수행된다.
파이버는 리액트 아키택처 내부에서 비동기로 이뤄진다. 이러한 비동기 작업과 달리, 실제 브라우저 구조인 DOM에 반영되는 것은 동기적으로 일어난다.
화면에 불완전한 요소를 표시하지 않도록 하기 위해 이러한 변경사항을 업데이트 하는 작업을 가상에서, 즉 메모리 상에서 먼저 수행해 최종 결과물만 실제 브라우저 DOM에 적용한다.
가상 DOM과 리액트의 핵심은 브라우저 DOM을 빠르게 그리고 반영하는 것이 아니라 바로 값으로 UI를 표현하고 관리하는 것이다.
화면에 표시되는 UI를 자바스크립트의 문자열, 배열 등과 마찬가지로 값으로 관리하고 이러한 흐름을 효율적으로 관리하기 위한 메커니즘이 바로 리액트의 핵심이다.
key 속성 활용: 리스트 렌더링 시 key 속성으로 항목을 고유하게 식별해 불필요한 DOM 업데이트를 피하고, 효율적으로 업데이트