<dev.log/>;

리액트에서의 렌더링에 대한 이해

렌더링이란?

렌더링은 화면에 특정한 요소를 그려내는 것을 의미한다. 이 렌더링 과정을 잘 처리해주기 위해 Vanila JavaScript를 사용하지 않고 React같은 UI라이브러리 또는 프레임워크를 사용하는 것이다.

브라우저에서 렌더링은 DOM요소를 계산하고 그려내는 것을 의미한다. HTML과 CSS를 통해서 만들어진 DOM과 CSSOM이 결합되어 최종적으로 브라우저에 그려진다. 그리고 브라우저에서 제공하는 DOM API를 자바스크립트를 통해 호출하여 브라우저에 그려진 화면을 변화시킨다.

하지만 바닐라 자바스크립트를 이용해서 DOM에 직접 접근하고 수정하는 것, 그리고 이를 최적하 하는 것은 애플리케이션의 규모가 커지면 커질수록 관리하기 힘들어진다. 그래서 개발자들은 애플리케이션에서 보여주고 싶은 핵심 UI를 선언 하기만 하면 실제로 DOM을 조작해서 UI를 그려내고, 변화시키는 일은 라이브러리나 프레임워크가 대신 해주는 방식을 찾게 된다.

이런 니즈에 맞춰 React, Vue 등의 라이브러리, 프레임워크가 등장하게 되고 그 중에서 React가 현재 가장 많이 사용되고 있다. React는 선언형으로 실제 렌더링 과정은 React에서 대신 처리해주고, 개발자는 UI를 설계하는 것에만 집중할 수 있게 해준다.

리렌더링이 발생하는 시점은 언제일까?

우선 그전에 리액트에서 state를 사용하는 이유에 대해 알아야 한다. 리액트에서 state를 사용하는 이유는 UI와 상태를 연동시키기 위해서이다. 근본적으로 UI는 어떠한 데이터가 있고 그것을 보기 편한 형태로 표현한 것이다. 리액트는 이를 이해하여 UI와 연동되어야 하고, 변할 여지가 있는 데이터들을 state라는 형태로 사용할 수 있게 해줬다.

이런 이유로 인해서 리액트에서 리렌더링이 발생하는 시점은 state가 변했을 때이다. 특정 컴포넌트의 state가 변한다면, 해당 컴포넌트와 해당 컴포넌트의 하위 모든 컴포넌트들은 리렌더링이 발생하게 된다.

리액트의 렌더링 과정에 대해 좀 더 자세히 알아보자

리액트는 state가 변화했을 때 리렌더링을 발생시킨다고 했다. 이 과정은 state가 변화되고 최종적으로 브라우저상의 UI에 반영되기까지 각 컴포넌트에서는 크게 아래의 4단계를 거치게 된다.

  1. 기존 컴포넌트의 UI를 재사용할지 확인한다.
  2. 함수 컴포넌트는 컴포넌트 함수를 호출하고, class 컴포넌트는 render 메서드를 호출한다.
  3. 2의 결과를 통해서 새로운 Virtual DOM을 생성한다.
  4. 이전의 Virtual DOM과 새로운 Virtual DOM을 비교해서 실제 변경된 부분만 DOM에 적용한다.

이 과정을 왜 하는지, 근본적으로 Virtual DOM을 왜 사용하는지 알아야한다. 브라우저는 근본적으로 화면을 보여주기 위해 HTML, CSS, JavaScript를 다운로드 받고 그를 처리하여 화면에 픽셀 형태로 그려낸다. 이 과정을 CRP(Critical Rendering Path)라고 부른다.

CRP는 기본적으로 아래의 과정을 수행한다.

  1. HTML을 파싱해서 DOM을 만든다.
  2. CSS를 파싱해서 CSSOM을 만든다.
  3. DOM과 CSSOM을 결합해서 Render Tree를 만든다.
  4. Render Tree와 Viewport의 width를 통해서 각 요소들의 위치와 크기를 계산한다. (Layout)
  5. 지금까지 계산된 정보를 이용해 Render Tree상의 요소들을 실제 pixel로 그려낸다.(Paint)

이후 DOM 또는 CSSOM이 수정될때 마다 위의 과정을 반복한다. 따라서 이 과정을 최적하 하는 것이 퍼포먼스 상에 중요한 포인트이다. 위 과정 중에서 Layout, Paint 과정은 특히나 많은 계산을 필요로하는 부분이다. 따라서 리액트는 이 CRP가 수행되는 횟수를 최적화 하기 위해 Virtual DOM을 사용하는 것이다.

UI를 변화하기 위해서는 많은 DOM 조작이 필요하다. 하나하나의 DOM 조작마다 CRP가 수행될 것이고 이는 곧 브라우저에게 많은 연산을 요구하게 된다. 따라서 퍼포먼스를 저하시키는 요인이 될 수 있다. 리액트는 이를 해결하고자 Virtual DOM이란 개념을 도입한 것이다.

리액트에서는 UI의 변화가 발생하면 변화에 필요한 DOM 조작들을 매번 바로 Real DOM에 적용하는 것이 아니라, Virtual DOM이라고 불리는 리액트가 관리하고 있는 DOM과 유사한 객체 형태를 만들어낸다. 그리고 이전의 Vritual DOM과 새로운 Virtual DOM을 비교해서 실제로 변화가 필요한 DOM 요소들을 찾아낸다. 그 다음에 한 번에 해당 DOM 요소들을 조작한다.