
** 이 글에서는 렌더링 엔진이 작동하는 방식과 사용자 화면에 웹 페이지를 표시하는 방법을 알아볼거다.
* 먼저 설명하는 데에 쓰일 용어들의 의미를 알아보도록 하자.
파싱 (parsing) 이란?
컴퓨터 프로그래밍에서 말 그대로 "구문 분석" 을 의미한다.
즉, 컴퓨터가 이해할 수 있는 형태로 입력된 문서나 데이터를 분석하여 그 의미를 이해하고 처리하기 위한 작업이다.
웹 프로그래밍에서는 HTML, XML 등의 문서를 파싱하여 웹 페이지를 구성하거나 데이터를 추출하는 데에 사용된다.
DOM (Document Object Model) 이란?
HTML, XML 등의 문서를 파싱하여 웹 페이지를 구성하거나 데이터를 추출하는 데에 사용되는 API이다.
DOM은 문서를 트리 구조로 변환하여 각 요소를 노드로 표현한다.
이렇게 표현된 노드를 이용하여 문서의 내용을 변경하거나 원하는 요소를 선택할 수 있다.
JavaScript를 이용하여 DOM API를 사용할 수 있으며, 이를 통해 동적으로 HTML 요소를 생성하거나 변경할 수 있다.
렌더링 (Rendering) 이란?
Render는 어떤 데이터를 가져와서 화면에 그리는 것을 의미함.
웹 애플리케이션에서는 데이터를 가져와서 브라우저에 출력하기 위해 Render 함수를 사용한다.
Render 함수는 데이터와 HTML 문서를 함께 처리하여 브라우저에 출력할 수 있는 형태로 변환시킨다.
일반적으로, HTML과 CSS를 이용하여 디자인된 웹 페이지를 만들 때, 서버에서 데이터를 가져와서 변환한 후,
브라우저에 전달하여 출력하는 과정을 거치게 된다.
이때 사용되는 함수가 바로 Render 함수이다.
* HTML 문서는 트리 구조로 이루어져 있다.
트리 구조란?
계층적인 구조를 갖는 구조를 의미한다.
트리 구조에서는 각 요소를 노드라고 부르며, 이 노드들은 서로 부모-자식 관계를 가진다.
문서의 시작점인 <html> 요소를 루트 노드(Root-Node)라고 부른다.
루트 노드는 모든 다른 요소들의 부모 요소이면서, 모든 요소들은 루트 노드의 자식 요소이다.
트리 구조에서 각 요소는 다른 요소보다 하나의 깊이(depth)가 더 깊은 위치에 있다.
예를 들어서,
인터넷에서 웹페이지를 볼 때, 그 페이지는 HTML 태그를 통해 트리 구조로 표현된다.
가장 상위에는 <html> 태그가 있고, 그 안에 <head>와 <body> 태그가 있다.
<body> 태그 안에는 수많은 다른 태그들이 존재할 수도 있다.
여기서 태그들은 서로 계층적인 관계를 가지게 된다.
따라서, 부모 요소는 항상 자식 요소보다 더 위에 위치하며, 루트 노드를 제외한 모든 요소는 부모 요소를 가지고 있다.
What is a Rendering?
웹 개발자로서 우리는 매일 브라우저를 사용하여 개발된 웹 사이트를 실행한다.
근데 웹 페이지를 렌더링하기 위해, 이루어지는 프로세스에 대해 생각해 본 적은 있을까?
렌더링 엔진은 HTML 및 이에 연결된 다른 리소스를 해석해서 화면에 웹 페이지를 표시하는 브라우저 구성 요소 중 하나이다.
웹 페이지를 렌더링하려면 일련의 단계를 거쳐야 한다.
렌더링 순서
DOM → CSSOM → Render tree → Layout → Paint
아래 HTML 문서 예시를 통해 각 단계를 자세히 살펴보도록 하자.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<link rel="stylesheet" href="styles.css">
<title>렌더링 엔진에 대해서 알아보자고! -bokueyo- </title>
</head>
<body>
<div class="container">
<h1>Rendering engine process</h1>
<ul>
<li>DOM</li>
<li>CSSOM</li>
<li>Render Tree</li>
<li>Layout</li>
<li>Paint</li>
</ul>
</div>
</body>
</html>
1. DOM(문서 개체 모델)의 트리 구성 :
- URL을 입력하고 엔터 버튼을 누르면 렌더링 엔진이 네트워크(서버) 또는 로컬 디스크에서 바이트 형식의 HTML 파일을 수신한다.
그런 다음 파일의 지정된 인코딩을 기반으로 이러한 바이트를 문자 로 변환해준다. (UTF-8은 HTML의 표준 문자 인코딩 형식임). - 문자 변환 후 각 문자열은 W3C에서 지정한 HTML5 표준을 사용하여 고유한 토큰 으로 변환된다.
- 다음 단계에서 이러한 토큰은 속성 및 규칙이 있는 노드 개체 로 변환된다.( 참고로 각 HTML 태그는 개별 노드 객체임 )
- 마지막 단계에서 렌더링 엔진은 노드 개체를 사용하여 트리 종류의 구조를 구성한다.
위의 HTML 예시 문서에 대한 DOM 트리는 아래와 같이 렌더링 엔진이 페이지의 모든 처리에 사용함.
DOM 트리가 HTML의 요소와 요소 간의 관계를 나타내긴 하지만 요소가 렌더링될 때 어떻게 표시되는지 알려주지는 않는다.
이는 CSSOM에서 처리한다.
2. CSSOM(CSS 개체 모델)의 트리 구성 :
HTML 요소에 스타일을 적용하는 방법에는 외부 CSS 사용, 스타일 태그를 사용하는 CSS , HTML 요소에 스타일 속성을 사용하는 인라인 방법 또는 JavaScript를 사용하는 등 다양한 방법이 있다.
HTML이 파싱되는 동안 렌더링 엔진이 이러한 형식(외부, 내장, 인라인) 중 하나의 스타일을 만나면
DOM 트리와 같은 구조와 트리를 '구문 분석'하고 구성하며, 이 트리를 CSSOM 트리라고 한다.
여기에서도 렌더링 엔진은 아래 단계를 거쳐 DOM 트리를 구성할 때와 마찬가지로 CSSOM 트리를 생성한다.
바이트 → 문자 → 토큰 → 노드 → CSSOM
CSSOM 트리에서 각 노드는 고유한 스타일과 상위 노드에서 계단식으로 이어지는 스타일을 보유한다.
위에서 예시로 들었던 HTML 코드를 통해 설명하겠다.
위의 HTML 마크업에 아래의 CSS를 적용한다고 가정해보자.
body {
font-family: sans-serif;
color: #fff;
}
.container {
background: cornflowerblue;
padding: 20px;
}
h1 {
font-size: 40px;
margin-bottom: 30px;
}
ul {
padding: 0;
text-align: center;
font-size: 24px;
}
li {
list-style-type: none;
margin: 25px 0;
padding: 10px;
border: 3px solid #fff;
}
위 CSS의 경우 CSSOM 트리는 아래와 같다.
여기서 파란색으로 강조 표시된 속성은 상위 노드(본체)에서 계단식으로 연결된다.
CSSOM 트리에서 렌더링 엔진은 헤드, 메타, 링크 및 제목 태그에 스타일이 없기 때문에 무시한다.
지금까지 렌더링 엔진은 HTML 및 CSS를 기반으로 DOM 및 CSSOM 트리를 생성했다.
그러나 이 두 트리는 모두 독립적이다.
DOM 트리는 콘텐츠를 구성, CSSOM 트리는 스타일을 구성했다.
그렇다면 Rendering 엔진은 두 트리를 어떻게 병합하여 화면에 픽셀을 렌더링 할까?
3. 렌더링 트리 (Rendering Tree):
렌더링 엔진은 DOM 및 CSSOM 트리를 결합하고 렌더링 트리를 형성한다.
렌더 트리는 두 트리에서 보이는 노드만 구성하고
스크립트, 메타, 제목 태그 및 CSS를 통해 숨겨진 노드(display: none;가 있는 노드)와 같이 화면에 렌더링되지 않을 노드는 무시한다
보이는 각 노드에 대해 일치하는 CSSOM 규칙을 찾아 적용한다.
이와 같이 표시되는 모든 노드의 콘텐츠 및 스타일 정보를 모두 포함하는 위에 렌더링 트리를 시각화 시킬 수 있음.
4. 레이아웃 (Layout) :
지금까지 렌더링 엔진은 표시되어야 하는 노드와 계산된 스타일을 계산했다.
그러나 장치의 ViewPort 내에서 정확한 위치와 크기를 알지 못하는데 이걸 레이아웃 단계 에서 실행한다.
이 단계에서 렌더링 엔진은 루트에서 렌더링 트리를 탐색하기 시작하고
표시되는 각 요소의 정확한 크기와 페이지에 인쇄되어야 하는 위치를 계산한다.
렌더링 엔진이 각 노드의 레이아웃 정보를 계산하기 때문에 이 프로세스를 Layout (레이아웃) 이라고 한다.
<스크롤, 창 크기 조정 또는 DOM 조작과 같은 이벤트에서 요소 크기 또는 위치가 변경될 수 있기 때문에
이 프로세스를 Reflow (리플로우) 라고 부르기도 한다고 함.>
5. 페인트 (Paint) :
지금까지 렌더링 엔진은 보이는 요소 스타일, 크기 및 위치를 계산했다.
이제 드디어 렌더링 엔진이 화면에 요소를 배치할 준비가 된 것이다!
이 단계에서 렌더 트리의 각 노드는 화면의 실제 픽셀로 변환된다.
렌더링 엔진이 이전 단계의 출력을 가져오고, 사용자의 화면에 요소를 인쇄하기 때문에 이 단계를 페인트(Paint) 라고 한다.
페인팅 작업 후 사용한 코드 예제의 최종 결과물이다.
짧게 말하자면,
1. 서버로부터 HTML을 받아옴.
2. HTML을 파싱(parsing)해서 DOM Tree 를 만든다.
3. css 파일, 스타일 요소를 파싱(parsing)해서 CSSOM Tree 를 만든다.
4. DOM Tree와 CSSOM을 결합해서 Rendering Tree 를 만든다.
5. Rendering Tree 의 요소들의 크기와 위치를 계산한다.
6. 계산된 크기와 위치에 맞게 화면에 페인팅(출력)한다.
그리고 이 과정은 사용자와의 상호작용이나 javascript 실행에 의해 동적으로 여러번 반복될 수 있다.
이를 'Reflow(리플로우)' 와 'Repaint(리페인트)' 라고 한다.
'개발 > CS' 카테고리의 다른 글
Network 정리 - (1) (0) | 2024.03.19 |
---|---|
HTTP 와 HTTPS 그리고 SSL (0) | 2023.07.20 |
논리회로 간단하게 훑어보기? (0) | 2023.03.06 |
개발 블로그
포스팅이 좋았다면 "좋아요❤️" 누르기 !