맨 땅에 프론트엔드 개발자 되기

React Virtual DOM 비교 원리와 얕은 비교 본문

코딩 공부 일지/React JS

React Virtual DOM 비교 원리와 얕은 비교

헬로코딩 2022. 3. 29. 11:45
728x90

React 가상 돔(Virtual DOM)

React에서는 가상 돔을 사용한다. 이 가상 돔은 실제 DOM(Document Object Model)을 조작하는 방식이 아니라 실제 DOM을 모방한 가상의 DOM을 구성해서 원래 DOM과 비교해서 달라진 부분을 리렌더링 시켜주는 방식으로 작동을 한다. 그런데 이 때 가상 돔을 잘 이해해야만 React의 '상태'를 잘 다룰 수 있다.

- Virtual DOM을 사용하는 이유

그렇다면, 왜 실제 DOM을 조작하지 않는지에 대해서 알아보자. Vanilla JS를 이용하여 DOM을 조작하는 방식은 무거운 작동방식이다. 실제 DOM에는 브라우저가 화면을 그리는데 필요한 모든 정보가 들어있기 때문이다. 그래서 React는 깜박거림 없이 부드러운 UX를 사용자에게 제공하기 위해 변경사항만 빠르게 파악하고 리렌더링 하기 위해 가상 DOM을 만들어 비교하는 방식을 채택했다. 

React는 성능 향상을 위해 실제 렌더링 된 UI를 내부적으로 JavaScript 객체로 따로 관리한다. 직접 DOM 노드를 생성하거나 접근해서 변경을 하는 것이 JavaScript 객체로 표현된 DOM 트리를 조작하는 것보다 훨씬 느리기 때문이다. (그러나 JavaScript 객체를 따로 관리하므로 메모리 사용량이 늘어난다는 단점이 있다. 일종의 DOM 캐싱으로 볼 수 있다.)

React가 가상 돔을 비교하는 원리

React는 실제 DOM의 UI를 가진 JavaScript 객체를 메모리상에 가지고 있다. 이 Vitual DOM은 변화를 감지하면 재조정(Reconcilation) 과정을 통해 실제 DOM과 동기화 한다. 재조정 과정은 크게 3단계로 나뉜다.

  1. UI가 변경을 감지하면 UI를 Virtual DOM으로 렌더링한다. (실제 화면 상에 렌더링 되는 것이 아니라 비교를 위한 가상 렌더링이다.)
  2. 현재 Virtual DOM과 이전 Virtual DOM을 비교해 차이를 계산한다.
  3. 변경된 부분을 실제 DOM에 반영한다.

React 얕은 비교(Shallow Compare)

React는 노드를 비교할 때 얕은 비교를 한다. 이 말이 무엇인가 하면, 먼저 JavaScript의 원시 자료형과 참조 자료형에 대한 이해가 바탕이 되어야 한다.

 

원시 자료형과 참조 자료형

원시 자료형과 참조 자료형 원시 자료형(Primitive Data Type) 원시 자료형은 객체가 아니면서 동시에 메소드도 가지지 않는 자료형을 말하며, 다음의 자료형을 말한다. string, number, bigint, boolean, undefin

babycoder05.tistory.com

React의 얕은 비교는 같은 레벨에서만 일어난다.

  • 숫자, 문자열, Boolean과 같은 원시 자료형은 값을 비교한다.
  • 배열, 객체 등 참조 자료형은 그 안의 값 혹은 attribute를 비교하지 않고, 그들의 레퍼런스(참조되는 위치)를 비교한다.

그러므로 배열을 직접 수정하는 방식, 예를 들어, push, pop 과 같은 메소드로 배열을 수정한 뒤 setState에 담아주어도 기본적으로 같은 참조 위치를 가지고 있기 때문에 값의 변화를 감지하지 못한다.

- React에서 객체 불변성을 유지하기

React에서 배열 값을 변경할 때는 객체와 마찬가지로, 불변성을 지켜주어야 한다. 이는 무슨 말이냐고 하면, 배열 혹은 객체의 원본을 수정하지 않고 상태 변경을 원하는 배열과 함수를 복사(깊은 복사, 얕은 복사는 안 됨)하고 나서 사용해야 한다는 뜻이다.

 

전개구문과 얕은 복사 & 깊은 복사

전개구문 ES6 에 추가된 문법으로 '...' 으로 표시하며, 구조분해할당과 함께 사용할 수 있고, 배열과 객체 등에 할당된 값을 전개해서 사용한다. 참조 자료형과 얕은 복사 & 깊은 복사 - 얕은 복사

babycoder05.tistory.com

그래서 원본을 수정하는 메소드인 push(), pop()과 같은 메소드를 사용해서 원본을 직접 수정하는 것은 React를 사용할 때 지양해야 한다. 대신, assign() 메소드를 사용하거나, 전개구문을 사용해서 복사를 한 뒤 그 복사값을 수정하고 setState에 담아주면 변경을 감지할 수 있다.

728x90