December 07, 2020
DOM 트리 구축을 위해서 HTML 소스를 파싱하여 DOM(Document Object Model) 트리를 구축한다.
CSS 파싱 후 CSSOM (CSS Object Model) 트리를 구축한다.
렌더링 차단 리소스(render blocking resource)로서, 먼저 리소스를 완전히 파싱하지 않으면 렌더링 트리를 구성할 수 없다. 즉, HTML과 달리 CSS는 계단식 상속 특성 때문에 부분적으로 실행 될 수 없다. 따라서 스타일 시트 문서 앞부분에 정의된 스타일은 문서 뒤에 정의된 스타일에 의해 무시 될 수 있다.자바스크립트 파일 실행
DOM과 CSSOM을 조합하여 렌더 트리 (Render Tree)를 구축한다.
렌더 트리를 배치한다 Layout/Reflow
렌더트리 그리기 Paint
직접 간단한 HTML 문서를 코딩하여 렌더링이 이론대로 잘 굴러가는지 알아보도록 하겠다.

위와 같이 귀염뽀짝한 페이지를 간단하게 만들어보았다.
가운데 위치한 아이묭의 사진을 누르면 아이묭의 앨범 목록이 토글되도록 구현했다. 이를 통해 렌더링 과정이 잘 진행되는지 보도록 하겠다. 위 페이지의 소스코드는 아래와 같다.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Example</title>
<link rel="stylesheet" href="style.css" />
</head>
<body>
<div>
<img
src="https://lastfm.freetls.fastly.net/i/u/770x0/48ba8a3d0ccc25b967b440e1abd279cb.jpg"
/>
<p>아이묭은 천재다</p>
</div>
<ul>
<li>2015 계란</li>
<li>2015 잡초는 죽지 않는다</li>
<li>2017 청춘의 익사이트먼트</li>
<li>2019 순간적 식스센스</li>
<li>2020 맛있는 파스타가 있다고 들어서</li>
</ul>
<script src="app.js"></script>
</body>
</html>style.css
@import url('https://fonts.googleapis.com/css2?family=Do+Hyeon&display=swap');
body {
background-color: #ffcc99;
font-family: 'Do Hyeon', sans-serif;
}
div {
text-align: center;
width: 100%;
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
z-index: 100;
}
div img {
width: 25%;
height: 25%;
border-radius: 50%;
border: 10px solid #fff;
cursor: pointer;
transition: border 1s;
}
div img:hover {
border: 10px solid #fcba03;
}
.Clicked {
border: 10px solid #fcba03;
}
ul {
background-color: #92eb34;
width: 280px;
padding: 15px 20px;
border-radius: 20px;
text-align: right;
visibility: hidden;
opacity: 0;
position: absolute;
left: 69%;
top: 50%;
transform: translate(-50%, -69%);
transition: visibility 0s, opacity 0.5s linear;
z-index: 10;
}
.ShowAlbumList {
visibility: visible;
opacity: 1;
}
ul li {
list-style: none;
color: black;
font-size: 1rem;
}
p {
font-size: 2rem;
text-align: center;
}app.js
const $div = document.querySelector('div')
const $ul = document.querySelector('ul')
const $img = document.querySelector('img')
const toggle = () => {
$ul.classList.toggle('ShowAlbumList')
$img.classList.toggle('Clicked')
}
$div.addEventListener('click', toggle)
페이지를 로드 했을 시 로그는 위와 같이 나타난다. 이를 통해 렌더링 과정이 위해서 설명한대로 진행됨을 알 수 있다.
Receive Data - Finish Loading - index.html 문서를 받아온다.Parse HTML - 받은 HTML에 대한 DOM 구문분석을 시작한다.Receive Response - Receive Data - style.css와 app.js 파일을 요청하고 받아온다.Parse Stylesheet- 받은 style.css 에대한 CSSOM을 생성해준다.Evaluate Script -자바스크립트 소스를 실행한다.Recalculate Style - Layout - Update Layer Tree -렌더 트리의 각 노드가 가지는 정확한 위치와 크기를 계산하여 렌더 트리를 배치한다. (Layout / Reflow )Paint 렌더트리를 그린다 (Paint)그렇다면 아이묭 사진을 클릭하여 클릭 이벤트(앨범 리스트 토글)가 발생한다면 어떻게 될까 ?
위는 아이묭 사진을 처음 클릭했을 때의 로그이다.
즉, 클릭 이벤트가 발생하여 UI에 변화가 생긴다면, 위와 렌더 트리 배치 (Layout / Reflow) 부터 다시 시작한 후 다시 렌더 트리를 그려주는 (Paint) 것을 알 수 있다.
네이버 D2 브라우저는 어떻게 동작하는가
HTML Critical rendering path의 이해
브라우저 렌더링 원리