
브라우저 렌더링과 가상돔(Virtual DOM)
- 브라우저 렌더링: 화면을 구성하는 과정
- 브라우저 주소 창 -> www.naver.com 주소를 입력하면 우리는 어떻게 네이버 화면을 보게되는걸까?
아래와 같은 과정을 거쳐 네이버 화면을 보게됩니다.
- 브라우저 주소 창 -> www.naver.com 주소를 입력하면 우리는 어떻게 네이버 화면을 보게되는걸까?
- 사용자 인터페이스(URI)
- 브라우저 엔진
- 렌더링 엔진(렌더링 과정)
- 네트워크 통신 / JS 해석기 / UI 백엔드
위와 같은 과정을 거쳐 화면이 만들어지고 그 만들어진 화면을 사용자가 보게되는 겁니다.
위 과정에서 3번 렌더링 엔진(렌더링 과정)에 대해 좀 더 자세하게 들여다보도록 하겠습니다.
렌더링 엔진
렌더링 엔진은 html, css, javascript의 내용을 토대로 브라우저 화면에 표시하는 일을 합니다.
- 파이어폭스: 게코 엔진
- 사파리, 크롬: 웹킷 엔진
- IE: Trident 엔진
여기서는 크롬, 웹킷을 기준으로 설명하겠습니다.
위 그림을 기억해주시기 바랍니다.
- HTML이 HTML 파서(해석기)를 통해서 DOM 트리를 생성하고 어태치먼트로 모입니다.
- Style Sheets 또한 CSS 파서를 통해서 스타일 규칙을 통해 어태치먼트로 모입니다.
- 이렇게 모여 렌더 트리를 만들고 ‘배치’, ‘그리기’를 통해서 화면에 표시가 되는겁니다.
위 과정을 조금 더 자세하게 보도록 하겠습니다.
-
DOM 트리 구축
하나의 html 페이지는 div, span 등 각각의 요소를 가집니다. 각 요소는 하나하나 노드(Node)로 설정이 되어 트리 형태로 저장되는데, 이를 DOM 트리라고 합니다.
예를 들어 div > span, span이라는 요소가 있다면 div라는 부모노드 밑에 span이라는 자식 노드가 2개 생기는 것입니다. -
렌더트리와 렌더레이어 생성
위 DOM 트리를 구축하고나면 렌더트리와 렌더레이어를 생성합니다.
각각의 노드는 CSS 파서에 의해 정해진 스타일 규칙이 적용되어 있습니다. span.color = “red”는 노드 색깔이 빨간색이다 등을 말하는 것이죠.
이런 규칙에 따라 CSSOM이라는 트리가 만들어지고 미리 만들어놓은 DOM 트리 내에 있는 노드와 함께 렌더객체(Render Object)가 생성되며 이들이 모여 병렬적인 렌더트리가 생성됩니다.
이때 display:none이 포함된 노드는 지워지고 font-size 등 상속적인 스타일은 부모노드에만 위치하도록 설계하는 등의 최적화를 거쳐 렌더레이어가 완성됩니다.
참고로 렌더객체와 렌더레이어는 1:1 대응이 되지 않을 수도 있습니다.
display:none으로 사라지는 노드들이 있을 수 있기 때문입니다. 하지만 DOM 트리와 렌더트리는 1:1 대응이 됩니다.
이렇게 렌더트리가 생성된 후 렌더레이어에 올려지게 됩니다.
렌더레이어가 완성될 때 GPU에서 처리되는 부분(CSS3D / video & canvas / filter / animation / transform: translateZ(0) 등)이 있으면 이 요소들은 각각 강제적으로 그래픽 레이어(Graphic Layer)로 분리됩니다. -
렌더레이어를 대상으로 Layout 설정
이때 좌표는 보통 부모를 기준으로 설정됩니다.
Global Layout은 브라우저 사이즈가 증가하거나 폰트 사이즈가 커지면 변경됩니다. -
렌더레이어를 대상으로 칠하기(paint)
픽셀마다 점을 찍는 듯 칠합니다. 이를 레스터화라고도 합니다. -
레이어 합치기(composite layer) 및 표기
각각의 레이어로부터 비트맵이 생성되고 GPU에 텍스처로 업로드됩니다.
그 다음 텍스처들은 서로 합쳐져 하나의 이미지로 렌더링되며 화면으로 출력됩니다.
굉장히 복잡한 위와 같은 과정을 거쳐서 우리의 눈에 브라우저 화면이 보이게되는 것입니다.
브라우저 렌더링과정과 가상돔(virtual DOM)
가상돔은 어떠한 불편한점을 해결하기위해 나온 컨셉인데, 기존에는 화면을 바꿀 때마다 렌더트리가 생성이되었습니다.
그러니까 어떠한 요소, span이나 div 태그가 바뀔 때마다 랜더트리를 다시 만들고 다시 레이아웃 잡고 칠하는 과정이 반복해서 계속 일어났던 겁니다.
즉, 요소를 3개를 수정한다면 3번의 그러한 과정이 일어났던 겁니다.
이러한 과정 자체가 별로 좋질 않았던 것이죠.
이를 해결하기 위해서, Virtual DOM이라는 것이 나온 것입니다.
가상돔은 가상적으로 UI를 저장했다가 실제 DOM과 연동하는 프로그래밍 컨셉이자 그걸 하는 자바스크립트 객체를 지칭합니다.
자바스크립트로 이루어진 DOM과 비슷한 객체를 의미하기도하고, 이 객체는 DOM API(getElementById, getQuerySelector 등을 의미)는 없고, DOM 프로퍼티만 존재합니다.
그래서 이 객체를 이용해서 수많은 요소가 수정이되어도 딱 한번 수정을해서 변화가 일어난 요소만 새로 렌더링합니다.
위 그림에서 오른쪽에 보이는
initial Model,View,update같은 것들이 다 VueJS나 ReactJS같은 것들이 되고,Virtual DOM이 중간계층이 되고, 실제돔을 바로 수정하지 않고 이 중간 계층을 거쳐서 수정을해서 수많은 요소가 수정이되어도 딱 한번만 수정을해서 그런 요소들 변환,, 렌더 트리로 인한 그런 수많은 과정들을 조금 더 줄일 수가 있는 것입니다.