Virtual DOM 이 무엇일까?
“DOM을 추상화한 가상의 객체”
regular DOM의 추상화 개념을 활용할 새로운 또 다른 DOM 이다. 이것은 빈번한 repaint와 reflow문제를 보완하였으며, Dynamic UI를 만들기 위해 적합한 기능들이 내장되어 있다. 그러므로 Virtual DOM은 SPA 모델의 웹 어플리케이션 에서는 regular DOM 보다 최적의 성능을 발휘한다.
그래서 왜필요하다고?
복잡한 SPA(싱글 페이지 어플리케이션) 에서는 DOM 조작이 많이 발생합니다. 그 뜻은 그 변화를 적용하기 위해 브라우저가 많이 연산을 해야한다는 소리고, 전체적인 프로세스를 비효율적으로 만듭니다.
만약 뷰에 변화가 생기면, 그 변화는 실제 DOM에 적용되기전에 가상의 DOM에 먼저 적용시키고, 그 최종적인 겨로가를 실제 DOM으로 전달해줍니다. 이로써, 브라우저 내에서 발생하는 연산의 양을 줄이면서 성능을 개선하는 겁니다.
정확한 예시!!
DOM 조작의 실제 문제는 각 조작의 레이아웃 변화, 트리 변화와 렌더링을 일으킨다는 겁니다. 그래서, 예를 들어
여러분이 30개의 노드를 하나하나 수정한면, 그뜻은 30번의(잠재적인)레이아웃 계산과 30번의 (잠재적인)리렌더링을 초래한다는 것이죠.
Virtual DOM은 그냥 뭐 엄청 새로운것도 아니고, 그냥 DOM 차원에서의 더블 버퍼링이랑 다름이 없는거에요.
변화가 일어나면 그걸 오프라인 DOM트리에 적용 시키죠. 이 DOM 트리는 렌더링도 되지 않기 때문에 연산비용이 적어요. 연산이 끝나고 나면 그 최종적인 변화를 실제 DOM에 던져주는 거에요. 딱한번만 하는겁니다.
모든 변화를 하나로 묶어서. 그러면, 레이아웃 계산과 리렌더링의 규모는 커지겠지만, 다시 한번 강조하자면
딱 한번만 하는거에요. 바로 이렇게, 하나로 묶어서 적용시키는 것이, 연산의 횟수를 줄이는 거구요.
사실 이 과정은 Virtual DOM이 없어도 이뤄질수 있어요. 그냥, 변화가 있을때 그 변화를 묶어서 DOM fragment에 적용한 다음에 기존에 DOM에 던져주면 돼요.
그러면, Virtual DOM이 해결하려고 하는 건 무엇이냐? 그 DOM fragment를 관리하는 과정을 수동으로 하나하나 작업할 필요 없이, 자동화하고 추상화하는 겁니다. 그뿐 아니라, 만약에 이 작업을 여러분들이 직접 한다면, 기존 값 중에 어떤게 바뀌었고 어떤게 바뀌지 않았는지 계속 파악하고 있어야하는데 (그렇지 않으면 수정할 필요가 없는DOM 트리도 업데이트를 하게 될 수 있으니까요) , 이것도 Virtual DOM이 이걸 자동으로 해주는거에요. 어떤게 바뀌었는지, 어떤게 바뀌지 않았는지 알아내주는거죠.
마지막으로, DOM 관리를 Virtual DOM이 하도록 함으로써, 컴포넌트가 DOM 조작 요청을 할 때, 다른 컴포넌트들과 상화작용을 하지 않아도 되고, 특정 DOM 을 조작할 것이라던지, 이미 조작했다던지에 대한 정보를 공유할 수 필요가 없습니다. 즉, 각 변화들의 동기화 작업을 거치지 않으면서도 모든 작업을 하나로 묶어줄수 있습니다.
이해를 도와주는 브라우저의 Workflow
reflow, repaint의 개념을 알기 위해서는 브라우저의 Workflow를 알아야한다.
DOM Tree 생성
브라우저가 HTML을 전달받으면, 브라우저의 렌더 엔진이 이를 파싱하고 DOM 노드(Node)로 이뤄진 트리를 만든다. 각 노드는 각 HMTL 엘리먼트들과 연관되어 있습니다.
Render Tree 생성
그리고, 외부 CSS파일과 각 엘리먼트의 inline 스타일을 파싱해요. 스타일 정보를 사용하여 DOM 트리에 따라 새로운 트리, 렌더트리를 만든다.
webkit 에서는 노드의 스타일을 처리하는 과정을 ‘attachment’라고 부른다. DOM 트리의 모든 노드들은 ‘attach’라는 메서드가 있다. 이 메소드는 스타일 정보를 계산해서 객체 형태로 반환한다.
이과정은 동기적(synchronous) 작업이고, DOM 트리에 새로운 노드가 추가되면 노드의 attch 메서드가 실행됩니다.
렌더 트리를 만드는 과정에선, 각 요소들의 스타일이 계산되고, 또 이 게산되는 과정에서 다른 요소들의 스타일 속성들이 참조됩니다.
Layout(reflow) & Painting
Layout(reflow) : 렌더 트리가 다 만들어지고 나면, 레이아웃 과정을 거쳐요. 각 노드들은 스크른의 좌표가 주어지고, 정확히 어디에 나타나야 할 지 위치가 주어집니다.
painting : 그 다음 작업은 렌더링 된 요소들에 색을 입히는 과정입니다. 트리의 각 노드들을 거쳐가면서 paint()메서드를 호출해요. 그리고 나면, 스크린에 원하는 정보가 나타납니다.
var style = document.body.style; // 캐싱
style.padding = "20px"; // reflow, repaint
style.border = "10px solid red"; // reflow, repaint
style.color = "blue"; // repaint (레이아웃이변경되진않았기때문에 reflow 안함)
style.backgroundColor = "#ffa"; // repaint
style.fontSize = "1em"; // reflow, repaint!
document.body.appendChild(document.createTextNode('hello world!')); // reflow, repaint
repaint는 색상이 변경되거나 글자의 내용이 바뀌었을 때 발생되는 연산이다. reflow는 하나의 DOM객체의 크기나 위치가 변경 되었을 때 (레이아웃의 변경작업), 다른 DOM 객체들의 위치와 크기가 함께 변경하는것을 말한다.
*주의: 사실 브라우저는 생박보다 멍청하지 않다. 위에 코드로 설명해놓은 구간의 한줄 한줄 마다 repaint와 reflow가 발생하는것은 아니다. 실제로는 style에 대한 작업이 더 없고 다른 연산으로 들어갈 때 Batched DOM Update가 발생하여 style변경에 대한 작업을 일괄적으로 처리하게 된다. 즉, 매 한 줄 마다 reapint, reflow연산을 하지 않는다는 것이다.
정리
Virtual DOM을 알기위해서는 브라우저 workflow에 대해서 알아야했다. 그걸 바탕으로 왜 virtual DOM이 알아봤는데 유래가 있긴하다.
그걸 알기 위해서는 react는 왜 존재하는가 부터 생각을 해야되고, 그거에 관련 내용을 링크로 남겨두겠다. 정말 잘 정리한 사이트가 있다. 간단히 요약하자면, 규모가 커지고 요구되는 사항들이 정적에서 동적인 웹페이지로 트랜드가 바뀌면서 성능상의 문제가 발생했기 때문에 추가된것이다.
우리가 직접 수정하는 방법도 있지만, 그러한 수고보다 virtual dom에서 변화를 자동화하고 추상화함으로써 생산력을 높이는겁니다. 많이 부족했던 내용도 많았지만 그래도 이렇게라도 virtual DOM을 좀더 알아가는 시간이었다.
참고
'prev > React' 카테고리의 다른 글
React Hook과 Closure의 관계(feat. useState) (0) | 2023.06.28 |
---|---|
프레임워크와 라이브러리 (0) | 2023.06.01 |
Hoisting 이란? (0) | 2023.05.31 |
브라우저 workflow & virtual DOM - 01 (0) | 2023.05.31 |
Portal (0) | 2023.04.04 |