- HTML의 Dom Tree를 추상화한 것.
- React는 state가 변경되면 새로 렌더링을 하는데, 실제 Dom Tree에 데이터를 렌더링 하기전에 먼저 virtual dom에 렌더링을 한 이후 변경된 부분을 확인하고 그 부분만 새로 교체하여 렌더링하기때문에 효율적이다.
- React만 가지고 있는 것은 아니고, React와 비슷한 언어들은 대부분 가지고있다고한다.
- 하지만 모던 브라우저(크롬, 사파리 등) 들은 DOM이 노드를 사용하지 않고 자바스크립트와 동일한 메모리모델을 쓰기때문에, 리엑트와 동일하게 바뀐것이 없다면 추가작업을 하지 않기때문에 더이상 큰 성능문제는 없다고한다.
dom과 virtual dom의 차이
Dom
- Document Object Model
- 브라우저의 렌더링 엔진에 의해 HTML문서를 파싱하고, HTML문서 안의 태그들을 브라우저가 이해할 수 있는 형태인 DOM을 생성한다.
- 따라서 HTML마크업과 DOM은 1:1관계를 맺게된다.
Virtual DOM
- Virtual DOM은 DOM을 모방하는 형태로 메모리상에서만 존재하는 가상의 DOM이다.
- DOM에 변화가 생길 경우, 새로 렌더링을 해야하는데 모든 노드들을 처음부터 다시 그리면 소모적인 렌더링이 발생한다.
- 그래서 Virtual DOM을 한 번 거쳐 미리 처리하고 저장한 후 실제 DOM에 업데이트할 수 있게 해준다.
- 메모리상에서만 동작하기때문에 훨씬 더 빠르게 동작되고, 변경사항만을 묶어 한 번만 렌더링을 실행시키므로 효율적이다.
- dom fragment를 관리하는 과정을 자동화/추상화해준다.
- 변경사항을 확인할 때에는 diffing알고리즘을 사용하는데 이 알고리즘은 아래와 같이 동작한다.
diffing 알고리즘
- React Element의 속성값만 변한경우 -> 속성값만 업데이트
- React Element의 태그 또는 컴포넌트에서 변화를 감지 -> 해당 노드를 포함한 모든 하위노드를 unmount한 후, 새로운 virtual dom으로 대체
dom fragment
- virtual dom과 같이 메모리상에서만 존재하는 객체이다.
- dom fragment를 수동으로 조작하여 DOM의 연산횟수를 줄이는 것이 가능하다.
- 하지만 일일이 DOM의 업데이트여부를 확인하고 수정해줘야하므로 복잡한 어플리케이션에서 dom fragment를 직접 관리하는 것은 거의 불가능한 일이다.
- 아래와같이 fragment객체를 만들어서 한 번만 렌더링되게 할 수 있다고한다.
var list = document.createElement('ul');
var numbers = ['one', 'two', 'three'];
var frag = new DocumentFragment()
numbers.forEach(function (num) {
var li = document.createElement('li');
li.innerText = num;
frag.appendChild(li);
});
list.appendChild(frag);
Virtual DOM 의 장점
- 개발자가 직접 Dom 노드를 신경쓸 필요가 없기때문에 단순하고 깔끔한 코드를 작성할 수 있다.
- 변경사항을 리액트가 적당히 모아서 처리한다.
리액트는 버츄얼돔이 바뀔때마다 브라우저에 바로 전달하지않고 적당히 모아뒀다가 브라우저에 전달한다.
그래서 복잡한 페이지에서도 한정된 브라우저 자원을 효율적으로 활용할 수 있다. 변경사항을 효율적으로 처리할 수 있다.
렌더링 과정
기존 브라우저의 렌더링 과정
(https://develocal.tistory.com/86)
더보기
렌더링 과정
6. HTML 파싱
- 렌더링 엔진은 받은 HTML 문서를 파싱하여 웹 페이지의 구조를 이해한다.
- 이 과정에서 HTML 요소, 태그, 속성 등을 해석하고, "콘텐츠 트리" 내부에서 태그를 DOM노드로 변환한다.
7. Render Tree 구축
- 브라우저는 파싱된 HTML과 CSS 정보를 결합하여 렌더링 트리를 생성한다.
- 렌더링 트리는 화면에 표시될 요소의 계층 구조를 나타낸다.
- 색상 또는 면적과 같은 시각적 속성이 있는 사각형을 포함하고 있는데 정해진 순서대로 화면에 표시된다.
8. 레이아웃 및 페인트
- 브라우저는 렌더링 트리를 기반으로 각 요소의 크기와 위치를 계산하고 화면에 표시한다.
- UI백엔드에서 렌더트리와 각 노드를 가로지르며 형상을 만들어낸다.
- 렌더링 엔진은 좀 더 나은 사용자 경험을 위해 모든 HTML을 파싱할 때 까지 기다리지 않고 레이아웃과 페인트를 시작한다.
- 따라서 전송을 기다리며 이미 받은 내용의 일부를 먼저 화면에 표시한다.
9. 자바스크립트 실행
- 웹 페이지에 포함된 JavaScript 코드가 실행된다.
- 이를 통해 동적인 기능을 추가하거나 상호작용을 가능하게 한다.
10. 이벤트 처리
- 브라우저는 사용자의 입력 및 이벤트(마우스 클릭, 키보드 입력 등)를 감지하고 처리한다.
- 이벤트 처리기를 사용하여 웹 페이지의 동작을 제어하고 사용자와 상호작용한다.
11. 통신
- 웹 페이지가 추가적인 데이터를 필요로 할 때, 브라우저는 서버와 통신하여 데이터를 요청하고 응답을 받는다.
- 이를 통해 웹 페이지는 실시간 업데이트 및 동적 콘텐츠를 제공할 수 있다.
12. 캐싱
- 브라우저는 이전에 다운로드한 리소스를 캐시에 저장하여 다음에 같은 리소스를 요청할 때 다시 다운로드하지 않도록 한다.
- 이로써 웹 페이지 로딩 속도를 향상시킬 수 있다.
13. 보안
- 브라우저는 웹 페이지의 보안을 강화하기 위해 다양한 보안 기술과 메커니즘을 사용한다.
- 예를 들어, HTTPS를 통한 데이터 암호화, 동일 출처 정책(Same Origin Policy)를 통한 보안 제한 등이 있다.
14. 웹 페이지 표시
- 최종적으로 브라우저는 렌더링된 웹 페이지를 화면에 표시하고 사용자에게 보여준다.
React의 렌더링 과정
1. render 단계
- React.createElement로 생성
2. reconciliation 단계
- 이전 Elements와 새로 생성된 elements 비교
3. commit 단계
- 바뀐 데이터가 있을 경우, DOM Update
결론
브라우저의 렌더링과정을 꽤 길고 복잡한데, 변경이 일어날 때 마다 작업을 하는 것은 비효율적이기때문에, virtual dom을 사용해서 변화가 생겼을 때만, 변화된 부분만 모아뒀다가 한번에 적용하기때문에 효율적이다.
참조
https://callmedevmomo.medium.com/virtual-dom-react-%ED%95%B5%EC%8B%AC%EC%A0%95%EB%A6%AC-bfbfcecc4fbb
'React' 카테고리의 다른 글
React - 화면 이동하기(Router, Link, Navigate) (0) | 2023.10.25 |
---|---|
React - 배열을 렌더링시 key를 써야 하는 이유 (0) | 2023.10.23 |
React - 데이터 다루기 (0) | 2023.10.20 |
React - state, react가 render하는 방식 (1) | 2023.10.18 |
React - 예제 프로젝트 dicegame 만들기 (0) | 2023.10.16 |