Virtual DOM이란?
브라우저 렌더링 과정
WebKit 엔진

DOM tree 생성 -> Render tree 생성 -> Layout -> Paintin
1. 개발자가 작성한 HTML을 브라우저가 전달받으면, 브라우저의 랜더엔진이 이를 HTML 파싱하고
DOM-node로 이루어진 트리를 생성.
2. CSS파일과 각 엘리먼트의 인라인 스타일을 파싱하고, 스타일 정보를 추가하고 렌더트리를 추가합니다.
3. 렌더트리가 만들어지고 나면, Layout 과정을 거칩니다. 각 노드들은 스크린의 좌표가 주어지고 정확히 어디에 위치할지 정해짐
4. 앞선 정보들로 모든 요소의 색을 입힌다.
DOM 조작의 비효율성 때문에 순서도를 설명했습니다.
HTML, CSS 파싱부터 화면에 Painting 하는 과정까지 전부 조작하게 됩니다.

*많은 연산과 비용을 수반하는 작업입니다.
프로그램 성능을 저하시킵니다.
SSR 성행 당시, DOM은 정적페이지를 보여주는 데 많이 사용됐다.
DOM의 동적인 변화가 큰 문제가 되지 않았다.
SPA와 CSR의 등장으로 DOM 업데이트가 상당히 복잡하게 업데이트되는 게 많아졌다.
DOM 조작을 통해 화면의 렌더링 비효율성을 해결하고, 최적화 필요성이 대두되어 Virtual DOM이 등장했다.

- 실제 DOM 노드 트리를 복제한, 자바스크립트 객체
Virtual DOM은 실제 DOM과 달리 class, style 등 속성을 가지고 있지만,
화면에 직접 변화를 줄 수있는 getElmentbyget() DOM api를 가지고 있지 않다.
Virtual DOM의 동작방식
브라우저가 DOM Tree가 생성되고, 애플리케이션 UI가 렌더 됨.
이때, Virtual DOM은 DOM Tree를 가벼운 버전으로 복사합니다.

그리고 DOM 노드에 변화가 생기면?
👉새로운 Virtual DOM 트리 재생성
DOM Node의 비효율성은 어디서 문제인가요?!
*DOM Tree 업데이트 과정에서 발생하는 것이 아니라, 렌더링 하는 과정에서 비싼 비용이 든다.
하지만, Virtual DOM은 렌더링 하지 않고, 메모리에서 Tree를 변경하는 일(가벼움)
Virtual DOM 내부 함수 보기
Diff 함수에서 매개변수로
- 이 전 상태의 DOM 트리
- 새롭게 만들어진 DOM Tree 받아옴
Previous, Current의 이름으로 받아 -> 변화된 부분만 확인한다.
diff(previous:VTree, current:VTree) -> PatchObject
변경된 부분만 실제 DOM Node에 적용하여 렌더링 과정 수행.
patch(rootNode:DOMNode, patches:PatchObject) -> DOMNode newRootNode
사실상의 역할
"버퍼링", "캐싱"의 역할, DOM 조작을 할 때마다, 브라우저 렌더링 과정을 반복하는 게 아니라 변화를 Virtual DOM에 반영해서
실제 DOM에 적용하여 한 번만 렌더링 하여 성능최적화.
React의 Virtual DOM
JSX: 자바스크립트 문법이 아니다.
Babel 툴에 의해 자바스크립트로 변화되는데, createElement 함수를 호출한다.
JSX -> 자바스크립트 객체로 변경
재조정: React에서 상태가 변화했을 때, 화면의 Virtual DOM을 활용하여 DOM을 업데이트 과정
쉽게 설명: Virtual DOM과 실제 DOM을 비교하고 일치시키는 과정
리액트는 (변경 전, 변경 후) Virtual DOM Tree를 둘 다 유지하고 있고, 스냅샷을 감지하여 변경된 부분만 실제 DOM에 적용
Diffing 알고리즘 사용해서 선별

list를 렌더 할 때, key prop이 있어야 한다는 경고메시지
리액트에서 key-prop을 사용하는 이유가 재조정과 깊은 연관이 있다.
react-element가 변화할 때, 재조정 과정에서
- 이전 Virtual DOM
- 새로 생긴 Virtual DOM
을 비교한다.