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);