ReactMasters / study

스터디 기록
1 stars 0 forks source link

11월 4주차 React는 왜 virtual DOM을 쓸까? #36

Open jordan-choi opened 2 years ago

jordan-choi commented 2 years ago

리액트는 실제 DOM을 직접 제어하지 않고 중간에 가상의 DOM인 Virtual DOM을 사용해 제어합니다. 리액트는 왜 Virtual DOM을 사용할까요?

브라우저의 동작 과정

먼저 Virtual DOM이 왜 필요한지 이해하기 위해 브라우저의 동작 과정을 간단하게 살펴보겠습니다.

웹킷(Webkit) 엔진을 기준으로 설명하였습니다. 사파리는 Webkit엔진을, 파이어폭스는 Gecko 엔진을, 크롬과 오페라(버전 15 이상)는 Blink엔진을 사용합니다.

웹킷 동작 과정

브라우저 엔진이 HTML 파일을 받으면, 렌더링 엔진은 아래의 과정을 차례로 수행하여 요청받은 콘텐츠를 화면에 표시합니다.

  1. DOM 트리 생성: ****렌더링 엔진이 HTML 파일을 파싱하고 DOM 노드로 구성된 DOM 트리를 생성합니다.
  2. Render 트리 생성: CSS 파일(인라인 CSS, 외부 CSS 파일)도 파싱하여 CSSOM 트리를 생성한 후, DOM 노드와 시각 정보를 연결하여(attachment) 렌더 트리를 생성합니다. 이 과정은 동기적으로 일어납니다. 렌더링 엔진은 사용자 경험을 위해 모든 HTML을 파싱할 때까지 기다리지 않고 배치(Layout)와 그리기(Painting) 과정을 시작합니다.
  3. 배치(layout): 렌더 트리를 구축한 후, 렌더트리에서 레이아웃을 실행합니다. 렌더 트리의 모든 노드는 스크린 상 정확한 위치와 크기를 가지게 됩니다.
  4. 그리기(Painting): 개별 노드를 화면에 그립니다.

Virtual DOM

DOM을 변화시킬 때마다, 렌더 트리를 재생성하고, 재배치하고, 재페인팅합니다. 수많은 DOM 조작을 포함하는 복잡한 SPA(Single Page Application)의 경우, 브라우저가 많은 복잡한 연산을 해야할 것입니다.

리액트는 가상의 DOM, Virtual DOM을 두어 개발의 편의성과 성능을 개선했습니다. DOM을 직접 제어하지 않아 개발의 편의성은 올라가고, 중간에 가상의 DOM을 둠으로써 브라우저에서 발생하는 연산의 양을 줄였습니다.

Virtual DOM(이하 VDOM)은 이름 그대로 가상의 DOM입니다. 리액트 공식문서에서는 아래와 같이 설명하고 있습니다.

Virtual DOM (VDOM)은 UI의 이상적인 또는 “가상”적인 표현을 메모리에 저장하고 ReactDOM과 같은 라이브러리에 의해 “실제” DOM과 동기화하는 프로그래밍 개념입니다. 이 과정을 Reconcilation이라고 합니다.

만약 view에 변화가 생기면, 실제 DOM에 적용되기 전 VDOM에 먼저 적용시킵니다. VDOM이 업데이트되면, 리액트는 VDOM을 직전 업데이트 시 VDOM의 스냅샷과 비교해 어떤 컴포넌트를 업데이트해야할 필요있는지 알아냅니다. 이 때 diffing algorithm이 사용됩니다.

Virtual DOM에서 주의할 점

  1. Life Cycle에서의 갱신
    • Life Cycle의 메서드(e.g., componentDidMount())에서 state를 변경하면, 해당 컴포넌트를 변경 대상 컴포넌트로 등록하고 VDOM을 갱신하는 배치 처리가 다시 시작됩니다.
    • componentDidMount() 내에서 state 변경 시 render()가 두 번 호출되므로 주의해야 합니다 [참고].
    • componentDidUpdate()의 경우 갱신이 일어난 직후에 호출되기 때문에 이 메서드 내에서 state 변경 시 무한 루프에 빠질 수 있습니다 [참고].
  2. 불필요한 렌더링을 막기위한 key prop
    • 이 때, 무의미한 랜덤값 사용은 지양합니다.
  3. 이벤트 리스너의 변수 저장
    • 이벤트 리스너를 인라인으로 생성해서 등록하면 같은 함수라도 레퍼런스가 달라 변경이 있다고 인식합니다.
    • 이벤트에 할당하는 함수를 매번 생성하기보단, 컴포넌트 생성자에서 필요한 함수를 변수에 저장해 사용하는 것이 좋습니다.

정리

참고 자료