Virtual Dom

인범·2023년 8월 13일
post-thumbnail

요즘 웹 성능을 개선하면서 내가 그냥 대충 알고 있던 개념을 좀 더 제대로 이해하고 정리할 필요를 느꼈다. 그리고 오늘은 그 중 virutal dom에 대해 말하고자 한다.


웹 성능을 개선할때 초기 랜더링 또는 리랜더링될때를 자세히 들여다 보면 정말 많은 일이 일어나고 있다.

virtual dom을 이해하기 전에 브라우저 랜더링 과정을 간단하게 짚고 넘어가자

브라우저 랜더링 과정

  1. DOM + CSSOM
    다운로드 받은 html 파일과 css 등 화면을 그리는데 필요한 리소스를 가지고 브라우저가 이해할 수 있는 형태로 변환하는 파싱 과정
  2. 랜더 트리
    DOM과 CSSOM의 결합으로 생성되고 화면에 표시되는 각 요소의 레이아웃을 계산하는데 사용
  3. 레이아웃
    화면 구성 요소의 위치나 크기를 계산하고 해당 위치에 배치하는 작업
  4. 패인트
    배치된 요소에 색을 채워 넣는 과정
  5. 컴포지트(composite)
    각 레이어를 합성하는 작업

요소가 바뀔때마다 위 랜더링 과정을 모두 또는 대부분 거친다. 그럼 정말 많은 요소가 들어가고 특정 state가 바뀔때 그로 인해 변경되는 상태와 요소가 많으면 정말 많은 랜더링을 거칠테고 PC 자원을 정말 많이 사용하고 복잡해질 수록 사이드 이팩트를 관리하기가 정말 힘들 것이다.

컴퓨터 공학에서는 이런 비효율적인 문제를 효율적으로 해결하기 위해서는 적절한 메모리를 사용하여 최적화하는 방법을 선택하고, 동작이 복잡해지면 해질 수록 이를 추상화해서 해결하고자 한다. 그렇게 나온 것이 virtual dom이다.

Virtual dom

Virtual dom은 공식 문서에서 다음과 같이 설명하고 있다. UI의 이상적인 또는 "가상"적인 표현을 메모리에 ReactDOM과 같은 라이으러리에 의해 "실제" DOM과 동기화하는 프로그래밍 개념이고 이과정을 재조정(Reconciliation)이라고 한다.

이렇게 되면 아무리 복잡한 변경이 발생하더라도 최종적으로 변경된 virtual dom와 실제 dom을 비교하여 최소한만 변경되기 때문에 컴퓨터 자원을 아낄 수 있고 사이드 이팩트도 최소화할 수 있다.

여기서 비교라는 과정을 거치게 되는데 여기서 리액트는 두가지 가정을 통해 n개의 엘리먼트에 대해 O(n) 복잡도의 휴리스틱 알고리즘을 구현했다.

  1. 서로 다른 타입의 두 엘리먼트는 서로 다른 트리를 만들어낸다.
  2. 개발자가 key prop을 통해, 여러 랜더링 사이에서 어떤 자식 엘리먼트가 변경되지 않아야 할지 표시해줄 수 있다.

매우 어려운 과학이나 수학문제 같은 경우는 가정을 어떻게 하느냐에 따라 문제가 굉장히 쉬워지는 경우가 있다. 1번의 케이스는 또한 그런 것 같다.

2번의 케이스는 우리가 리액트를 처음 접해서 map을 통해 컴포넌트를 랜더링 할때 자주 맞닥들이는 문제였다. 이제는 왜 그렇게 key를 넣어주라고 했는지, drag & drop과 같은 index가 자주 바뀌는 경우에는 index를 함부로 사용하면 문제가 생기는지 더 정확하게 알 것이다. 리액트 작동방식이 이렇기 때문이다.

마지막으로 공식문서에서는 virtual dom은 변경된 state에 따라 어떻게 ui에 반영할지에 대해 굉장히 복잡한 로직을 통해 추상화시켜놨기 때문에 setState을 비동기적으로 할 수 밖에 없었다고 한다. 이런 좀 더 deep하고 흥미로운 사실을 알아갈 때마다 정말 즐겁고 내가 개발자가 된 게 다행이라는 생각이 든다.

1개의 댓글

comment-user-thumbnail
2023년 8월 13일

좋은 글 감사합니다. 자주 방문할게요 :)

답글 달기