이 블로그는 브라우저의 렌더링 과정 - Seungwon Go와 객체 모델 생성 - Ilya Grigorik 두 글을 정리한 글입니다.
한 마디로 렌더링을 표현하자면 (실시간으로) 화면에 표시할 웹 페이지를 생성하는 과정 이다.
HTML과 CSS 그리고 JavaScript 등 개발자가 작성한 문서가 브라우저에 출력되는 것이다.
사용자가 웹 사이트에 접속하면, 서버로 부터 HTML, CSS 등 웹 사이트에 필요한 리소스(프로그램들이 활용할 수 있는 데이터)를 다운받는다.
브라우저가 이 페이지를 렌더링 하기 위해서는 HTML 코드는 DOM, CSS는 CSSOM(CSS 객체 모델) 트리는 생성해야 한다.
위 그림처럼 "바이트 -> 문자 -> 토큰 -> 노드 -> DOM" 순서로 진행 된다.
이 전체 프로세스의 최종 결과가 이 DOM이며, 브라우저는 이후 모든 페이지 처리에 이 DOM을 사용한다.
브라우저는 위의 DOM을 생성하는 과정에서 외부 CSS 스타일시트를 접하게 된다. 브라우저는 페이지를 렌더링하는 데 이 소스가 필요할 것이라고 생각하고 CSSOM 트리를 생성한다.
HTML과 같은 과정을 반복한다.
"바이트 -> 문자 -> 토큰 -> 노드 -> CSSOM"
그 결과는 다음과 같다.
브라우저가 DOM 및 CSSOM을 렌더링 트리에 결합 한다. 이 트리는 페이지에 표시되는 모든 DOM 콘텐츠와 각 노드에 대한 모든 CSSOM 스타일 정보를 캡처한다.
최종 결과는 화면에 표시되는 모든 노드의 콘텐츠 및 스타일 정보를 모두 포함하는 렌더링 트리이다.
렌더링 트리가 생성되었으므로 '레이아웃' 단계로 진행할 수 있다.
지금까지 표시할 노드와 해당 노드의 계산된 스타일을 계산 했다. 하지만 기기의 ViewPort 내에서 노드의 정확한 위치와 크기를 계산하지는 않았다.
이러한 과정을 진행하는 것이 '레이아웃' 단계이다.
경우에 따라서 '리플로우'라고도 한다.
<body>
<div style="width: 50%">
<div style="width: 50%">Hello world!</div>
</div>
</body>
위와 같이 중첩된 div가 있다고 하자. 상위 div
는 노드의 표시 크기를 ViewPort 너비의 50%로 설정하며, 하위 div
는 해당 너비를 상위 항목 너비의 50%로 설정한다.
Layout이 완료될 때 브라우저가 'Paint Setup' 및 'Paint' 이벤트를 발생한다.
이러한 작업은 렌더링 트리를 화면의 픽셀로 변환한다.
주요 렌더링 경로를 최적화하는 작업은 총 단계의 시간을 최소화 하는 것이다.
이렇게 하면 초기 렌더링과 업데이트의 시간을 줄여준다.
먼저 언급하고 가자면
Reflow
는Repaint
보다 성능에 더 큰역할을 야기한다.
리플로우는 해당 요소와 관련된 모든 요소의 레이아웃을 재 계산하기 때문이다.
리플로우는 변경사항을 반영하기 위해서 렌더링 트리를 생성하고 레이아웃 과정을 다시 수행한다. 그리고 실제 이 결과를 화면에 그리기 위해 다시 페인팅 단계를 실행한다.(리플로우가 일어나면 반드시 리페인트를 수행한다.)
하지만 리페인트만 일어나게 되면, 레이아웃에 변화를 일으키지 않고 바로 리페인트만 수행한다.
Reflow가 일어나는 대표적인 속성은 position, width, height, font-size, font-wieght, border, padding, margin 등이 있다.
Repaint가 일어나는 대표적인 속성은 background, box-shadow, color, text-decoration, visibility 등이 있다.
대표적으로 transform, opacitiy 가 있다.
브라우저의 렌더링 과정 - Seungwon Go
객체 모델 생성 - Ilya Grigorik
브라우저 렌더링 과정 - 박스여우