- Published on
브라우저의 동작 원리
- Authors
- Name
- Na Hyunwoo
혹시 프론트 공부를 하시면서 위의 그림을 본 적이 있으신가요 ?
만약 없으시다면 운이 좋으신 겁니다. 왜냐하면 웹 프론트엔드 개발이 결국 위의 구조에서 일어나는 변화이기 때문입니다. 즉, 웹 프론트엔드 개발의 뼈대가 되는 핵심 개념이기 때문입니다.
중요 렌더링 경로(Critical Rendering Path)
위의 사진은 결국 Critical Rendering Path. 즉, 브라우저가 하나의 화면을 그려내는 과정을 나타내는 그림이라고 할 수 있습니다. 이 과정을 개략적으로 설명하면 다음과 같습니다.
- 서버에서 응답으로 받은 HTML 데이터를 파싱한다.
- HTML을 파싱한 결과로 DOM Tree를 만든다.
- 파싱하는 중 CSS 파일 링크를 만나면 CSS 파일을 요청해서 받아온다.
- CSS 파일을 읽어서 CSSOM(SCC Object Model)을 만든다.
- Dom Tree와 CSSOM이 모두 만들어지면 이 둘을 사용해 Render Tree를 만든다.
- Render Tree에 있는 각각의 노드들이 화면의 어디에 어떻게 위치할 지를 계산하는 Layout과정을 거친다.
- 화면에 실제 픽셀을 Paint한다.
이제부터 각 단계를 더 자세히 살펴보겠습니다.
서버에서 응답으로 받은 HTML 데이터를 파싱한다.
브라우저 주소창에 url을 입력하고 엔터키를 치면 브라우저는 해당 서버에 요청을 보냅니다. 요청에 대한 응답으로는 아래와 같은 형태의 HTML 문서를 받아오게 되고, 이걸 하나하나 파싱(Parsing)하기 시작하면서 브라우저가 데이터를 화면에 그리는 과정이 시작됩니다. 이 때 미디어 파일을 만나면 추가로 요청을 보내서 받아옵니다. 만약 Javascript 파일을 만나면 해당 파일을 받아와서 실행할 때까지 파싱이 멈춥니다.
<html>
<head>
<meta charset="utf-8">
<link href="./style.css" rel="stylesheet">
</head>
<body>
<p>Hello, <span>web performance</span> students</p>
<div>
<img src="./image.png">
</div>
</body>
</html>
HTML에서 DOM Tree로
HTML이 DOM트리로 변환되는 과정에 대해서 살펴보겠습니다.
브라우저는 읽어들인 HTML 바이트 데이터를, 해당 파일에 지정된 인코딩(ex. UFT-8)에 따라 문자열로 바꾸게 됩니다.
바꾼 문자열을 다시 읽어서, HTML 표준에 따라 문자열을 토큰으로 변환합니다. 위의 이미지처럼 <html>
은 StartTag: html로, </html>
은 EndTag:html로 변환됩니다.
이렇게 만들어진 토큰들은 다시 노드로 바뀌는 과정을 거칩니다. StartTage: html이 들어왔으면 html노드를 만들고 EndTag:html을 만나기 전까지 들어오는 토큰들은 html노드의 자식 노드로 넣는 식으로 변환이 이루어지기 때문에, 이 과정이 끝나면 Tree모양의 Dom(Document Object Model)이 완성됩니다.
CSS에서 CSSOM으로
HTML을 파싱하다가 CSS링크를 만나면, CSS파일을 요청해서 받아오게 됩니다.
받아온 CSS파일은 HTML을 파싱한 것과 유사한 과정을 거쳐서 Tree형태의 CSSOM으로 만들어집니다.
CSS 파싱은 CSS 특성상 자식 노드들이 부모 노드의 특성을 계속해서 이어받는 규칙이 추가되는것을 제외하면 HTML 파싱과 동일하게 이뤄집니다.
만약 CSSOM 구성이 끝나지 않는다면, 이후의 Rendering 과정으로 나아갈 수 없습니다. 따라서 CSSOM을 구성하는 것이 끝나야 이후의 Rendering 과정을 시작할 수 있습니다. 그래서 CSS를 redering의 blocking 요소라고도 합니다.
DOM(Content) + CSSOM(Style) = Render Tree
CSSOM을 모두 만들었으면, DOM과 CSSOM을 합쳐서 Render Tree를 만듭니다. Render Tree는 DOM Tree에 있는 것들 중에서 화면에 실제로 ‘보이는’ 친구들만으로 이뤄집니다. 만약 CSS에서 display: none으로 설정하였다면, 그 노드와 자식 노드 전부 Render Tree에 추가되지 않습니다. 마찬가지로 화면에 ‘보이지 않는’ <head>
태그도 추가되지 않습니다.
위의 이미지를 보면 Render Tree에는 <head>
태그와 display: none인 <span>
태그가 사라진 것을 확인할 수 있습니다.
Render Tree
Render Tree를 더 자세하게 살펴봅시다. Render Tree는 Render Object Tree, Render Layer Tree와 같은 여러 가지 Tree를 가질 수 있습니다. 화면을 그리는 데에 필요한 모든 정보를 가지고 있는 Render Tree는 위의 여러 트리들이 합쳐져서 만들어집니다.
Render Object Tree는 위에서 말한 Dom Tree의 노드 중 화면에 보이는 것들만으로 이뤄진 트리입니다. block, inline, image, text, table과 같은 요소들이 Render Object가 됩니다. DOM Tree에서 <div>
는 Render Object Tree의 Block element로, <span>
은 Inline element로 옮겨집니다.
Render Object의 속성에 따라 필요한 경우 Render Layer가 만들어집니다.(Render Layer가 구성되는 속성에는 z-index와 같은 속성이 있습니다.) 그리고 이 Render Layer중 GPU에 처리되는 부분이 있으면 다시 Graphic Layer로 분리됩니다. Graphic Layer가 만들어지는 속성은 다음과 같습니다.
- CSS 3D Transform(translate3d, preserve-3d 등)이나 perspective 속성이 있을 때
<video>
또는<canvas>
요소- CSS3 애니메이션 함수나 CSS 필터 함수를 사용하는 경우
- 자식 요소가 레이어로 구성된 경우
- z-index 값이 낮은 형제 요소가 레이어로 구성된 경우
만약 Render Tree에 <div>
하나에 width 속성 정도만 있다고 하면, 레이어는 기본으로 만들어지는 하나만 사용합니다.
Layout(reflow)
화면에 보이는 노드들만을 가지고 있는 Render Tree가 다 만들어지면, Render Tree의 노드들이 화면의 어디에 위치할 지를 계산하는 Layout 과정을 거칩니다. CSSOM의 스타일 정보로 이 컨텐츠가 어떻게 생겨야 한다는 것은 알고 있지만, 현재 보이는 뷰포트를 기준으로 실제 이 컨텐츠가 어디에 위치해야 하는지를 또 계산해야 합니다. 여기서 CSS box model이 쓰이며, position(relative, absolute, fixed..), width, height 등등 틀과 위치에 관련된 부분들이 계산됩니다.
만약 width: 50%로 되어있는데, 브라우저를 리사이즈한다면, 보이는 요소들은 변함이 없으니 Render Tree는 그대로인 상태에서, layout 단계만 다시 거쳐 위치를 계산해서 그리게 됩니다.
이렇게 화면에 보이는 요소들이 어디에 어떻게 위치할 지를 정해주는 과정을 Webkit에서는 layout으로, Gecko에서는 reflow로 부릅니다.
Paint(repaint)
드디어 Render Tree의 각 노드들을 실제로 화면에 그리게 됩니다. visibility, outline, background-color와 같이 정말로 눈에 보이는 픽셀들이 여기에서 그려집니다.
만약에 Render Layer가 2개 이상이라면 각각의 Layer를 paint한 뒤 하나의 이미지로 Composite하는 과정을 추가로 거친 뒤에 실제로 화면에 그려지게 됩니다.
참고
박스 모델(box model)
모든 HTML 요소는 박스(box) 모양으로 구성되며, 이것을 박스 모델(box model)이라고 부릅니다. 박스 모델은 HTML 요소를 패딩(padding), 테두리(border), 마진(margin), 그리고 내용(content)로 구분합니다.
Webkit
웹킷은 웹 브라우저를 만드는 데 기반을 제공하는 오픈 소스 응용 프로그램 프레임워크이다. 애플에서 오픈소스로 개발하고 있다.
Gecko
게코는 웹 브라우저를 만드는 데 기반을 제공하는 오픈 소스 응용 프로그램 프레임워크이다. 모질라 재단에서 오픈소스로 개발되고 있다.