리액트가 수많은 개발자들 사이에서 사랑받는 이유 중 하나는 바로 빠른 속도.
리액트는 Virtual DOM을 이용해서 보다 효율적으로 원하는 페이지를 브라우저에 그려준다.
# DOM이란?
브라우저를 통해 어떤 웹사이트를 들어가면 제목도 있고, 버튼도 있고 사진도 있다.
이런 하나하나의 요소들을 element라고 부른다.
그리고 이 모든 것을 담고 있는 웹페이지를 문서, document라고 부른다.
브라우저는 이 페이지에 해당하는 HTML을 분석해서 화면에 띄워준다.
DOM은 이렇게 웹페이지에 들어가있는 element들을 tree형태의 구조로 표현한 것.
html이 이렇게 작성되어서 브라우저상에 올라왔다면 DOM은 오른쪽과 같은 구조를 가지고 있다.
DOM 트리 안에는 각각의 elemet에 상응하는 node가 들어있다.
개발자들은 DOM이 제공하는 API를 통해서 DOM구조에 접근을 하고, 원하는 element의 구조, 내용, 스타일을 입맛대로 변경시킬 수 있다.
이러한 행위를 "DOM 조작"이라고 한다.
만약 JS를 사용한다면, getElementById나 querySelector같은 API를 통해서 DOM구조 안에 있는 element에 접근해서 스타일, 구조, 내용을 수정할 수 있다.
# 가상 DOM이란?
그럼, 가상DOM이라는건 대체 무엇일까?
리액트는 가상DOM을 이용해서 실제 DOM을 조작하는 일을 엄청 빠르게 한다.
가상돔은 실제 돔과 같은 내용을 담고 있는 복사본이라고 생각하면 된다.
가상돔은 실제 돔이 아닌 자바스크립트 객체 형태로 메모리 안에 저장되어있다.
실제 돔 안에 있는 모든 엘리먼트들과 속성들을 똑같이 갖고 있다.
하지만, 가상 돔은 실제 돔과는 다르게 브라우저에 있는 문서에 직접적으로 접근을 할 수 없다.
그렇기 때문에 당연히 화면에 보여지는 내용을 직접 수정할 수도 없다.
여기까지 들으면, 가상돔은 뭔가 쓸데없어보인다.
왜 굳이 실제 돔의 복사본을 만들어서까지 메모리에 따로 저장을 해놓는걸까?
하지만 React는 이 가상돔을 아주 똑똑하게 사용해서 우리가 실제 돔을 조작하는데 걸리는 시간을 획기적으로 줄여준다.
# 실제 DOM 조작과정
웹페이지에 있어서 DOM조작은 없어서는 안되는 필수과정이다. 간단한 게시판 앱만 봐도 댓글을 달거나 좋아요를 누르는 등 간단한 일을 할 때도 화면에 보여지는 내용을 바꾸기 위해서는 DOM을 조작해야한다.
만약 왼쪽에 있는 내용을 가지고 있는 웹페이지를 오른쪽처럼 이런 식으로 수정을 하고싶다면 우리는 아래와 같이 자바스크립트 코드를 짜서 DOM을 조작하면 된다.
이런 식으로 DOM의 내용을 수정해줄 때마다 다음과 같은 과정이 수행된다.
1/ 브라우저가 현재 페이지의 HTML을 쭉 탐색해서 해당 element를 찾고,
2/ 해당 element와 자녀 element들을 제거한다.
3/ 새롭게 수정된 element들로 교체한다.
4/ CSS를 다시 계산하고 레이아웃정보를 알맞게 수정하고 새롭게 계산된 내용을 따라서 브라우저에 알맞게 그려준다.
DOM은 tree구조로 되어있기 때문에 tree에 있는 정보를 업데이트시켜주는 건 그리 무거운 작업은 아니다.
빠른 알고리즘을 통해서 tree를 효율적으로 업데이트 시켜줄 수 있다.
하지만 매번 DOM을 조작할 때마다 브라우저화면의 UI를 새롭게 그려주는 작업은 꽤 복잡하고 시간이 걸리는 작업이다.
만약 list안에 다섯개의 항목들의 스타일을 하나하나 따로 변경해야 한다면 이 과정을 다섯번이나 반복해서 화면에 그려줘야한다.
굉장히 비효율적이다.
# 가상DOM을 이용한 실제 DOM 조작과정
리액트는 가상돔을 이용해서 비효율적인 돔조작을 훨씬 더 빠르게 만들어준다.
가상돔은 실제돔과 똑같이 생긴 복사본. 실제돔 안에 있는 엘리먼트들과 속성들을 동일하게 가지고 있다.
하지만 실제 돔과는 다르게 직접적으로 화면에 보이는 UI를 조작할 수 있게 해주는 API를 제공해주지 않는다.
가상돔은 메모리에 저장되어있는 자바스크립트 객체에 불과하다.
그렇기 때문에 가상돔을 생성하고 접근하는 건 아주 가볍고 빠른 작업이다. 실제 브라우저에 접근하는게 아니므로.
그렇다면 리액트는 어떤 식으로 가상돔을 활용해서 보다 더 효율적으로 실제 돔을 조작할 수 있게 해주나?
리액트는 항상 두 개의 가상돔 객체를 가지고 있다.
- 첫번째 가상돔은 렌더링 이전 화면 구조를 나타내는 가상돔.
- 두번째 가상돔은 렌더링 이후에 보이게 될 화면 구조를 나타내는 가상돔.
우리가 이미 알고 있듯이 리액트는 state가 변경될 때마다 화면이 새로 렌더링이 된다.
리액트는 렌더링이 발생될 상황에 놓일 때마다 새로운 화면에 들어갈 내용이 담긴 가상 돔을 생성한다.
실제 브라우저에 그려지기 이전에.
그런 후에 렌더링 이전의 화면의 내용을 담고있는 첫번째 가상돔과 업데이트 이후의 내용을 담고 있는 두번째 가상돔을 비교해서 정확히 어느 엘리먼트들이 변했는지 찾아내어 (이러한 과정을 리액트는 'diffing'이라고 부른다. diffing은 효율적인 알고리즘을 사용해서 진행되기 때문에 정확히 어느 엘리먼트들이 변경되었는지 굉장히 빠르게 파악할 수 있다.) 바뀐 엘리먼트들을 파악한 다음에 리액트는 딱 그 바뀐 부분들만 실제 돔에 적용시켜준다. 그니까 딱 바뀐 엘리먼트들만 찝어서 실제 브라우저 화면에 적용시켜준다. 이걸 바로 Reconciliation(재조정)이라고 한다.
## Batch Update
리액트에 재조정 과정이 굉장히 효율적인 이유는 바로 "Batch Update" 덕분이다.
"Batch Update"라는 말은 조금 생소할 수 있다.
"Batch"는 집단 혹은 무리라는 뜻이다.
"Batch Update"란 변경된 모든 엘리먼트들을 집단으로 실제 돔에 한번에 적용 시켜주는 것.
만약 리스트 안에 열개의 항목이 바뀌었다면, 실제 돔을 10번 반복해서 조작하는게 아니라, 한꺼번에 바뀐 모든 부분들을 집단으로 적용시켜주는 것.
돔 조작에 있어서 가장 비용이 많이 드는 작업은 화면을 그려주는 작업이다.
Batch Update는 변경된 엘리먼트를 하나하나 따로 반복해서 그려주는 게 아니라, 변경된 내용을 한번에 다 받아와서 실제 돔에 한꺼번에 적용시켜주는 것이기 때문에 훨씬 더 빠르고 효율적이다.
# 정리
1. 리액트의 가상돔은 실제 DOM과 같은 내용을 담고 있는 복사본이다. 그리고 이 복사본은 자바스크립트 객체 형태로 메모리상에 저장되어 있다.
2. 리액트는 항상 두 개의 가상돔을 가지고 있다. 첫번 째 가상돔은 변경 이전의 내용을 담고 있고, 두번 째 가상돔은 변경 이후에 보여질 내용을 담고 있다.
3. 변경된 내용이 화면에 새롭게 그려지기 이전, 실제 DOM이 변경되기 이전에 리액트는 두 개의 가상돔을 비교해서 정확히 어떤 부분이 바뀌었는지 효율적으로 비교하여 파악한다. 그리고 이러한 과정을 Diffing이라고 부른다.
4. Diffing을 통해 변경된 부분들을 파악한 이후, 리액트는 Batch Update를 수행함으로 실제 DOM에 한번에 적용시켜준다.
그리고 이러한 과정을 Reconciliation, 재조정이라고 한다.
*참고영상
https://www.youtube.com/watch?v=gc-kXt0tjTM
'Computer Science' 카테고리의 다른 글
명령형 프로그래밍 vs 선언형 프로그래밍 (1) | 2024.01.25 |
---|---|
'빌드'란? (0) | 2023.12.08 |
네이티브 앱 vs 크로스플랫폼 앱 vs 모바일웹앱 vs 하이브리드 앱 (0) | 2023.11.25 |
컴파일러 vs 인터프리터 (0) | 2023.11.24 |
객체지향 프로그래밍에 대해서 (0) | 2023.11.18 |