Critical Rendering Path
렌더링 경로의 이해
https://bitsofco.de/understanding-the-critical-rendering-path/
서론
- CRP(Critical Rendering Path)
브라우저가 서버에서 페이지에 대한 HTML response를 받으면, 화면에 픽셀을 그리기 전, 수행해야 할 많은 단계 중, 페이지의 초기 페인트를 위해 ==브라우저==가 실행해야 하는 시퀀스
- DOM Tree 구성
- CSSOM Tree 구성
- JavaScript 실행
- Render Tree 생성
- Layout 생성
- Paint
- ...

본론
1. DOM Tree 구성
- DOM Tree : 완전히 구문이 분석된 HTML 페이지의 ==개체 표현==
- root 요소인 **\<html>에서 시작하여, 페이지의 각 요소/텍스트에 대한 노드가 생성된다.
- 다른 요소 내에 중첩된 요소는 하위 노드로 표시되며, 각 노드에는 해당 요소에 대한 전체 특성이 포함된다.
- 부분적인 실행이 가능하다 ! 콘테츠가 페이지에 나타나기 시작하기 위해 ==전체 문서를 로드할 필요가 없다.== (단, CSS, JavaScript가 페이지의 Rendering blocking을 야기할 수 있다. 아래 내용을 참조)
<html>
<head>
<title>Understanding the Critical Rendering Path</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<header>
<h1>Understanding the Critical Rendering Path</h1>
</header>
<main>
<h2>Introduction</h2>
<p>Lorem ipsum dolor sit amet</p>
</main>
<footer>
<small>Copyright 2017</small>
</footer>
</body>
</html>
DOM Tree 의 생성

2. CSSOM 트리 구성
- CSSOM( CSS 개체 모델 ) : DOM과 관련된 스타일의 개체 표현
- 명시적으로 선언되었는지 또는 암시적으로 상속되었는지 여부에 관계없이 각 노드에 대한 관련 스타일이 포함되어 있다.
CSS 예시
body { font-size: 18px; }
header { color: plum; }
h1 { font-size: 28px; }
main { color: firebrick; }
h2 { font-size: 20px; }
footer { display: none; }
CSSOM Tree의 생성

- CSS는 'render blocking resource(렌더링 차단 자원)'으로 여겨지며 완전한 구문 분석 없이는 Render Tree를 구성할 수 없다 .
- CSS는 HTML과 달리 계단식 특성을 상속하기 떄문에 부분적인 사용이 불가하다.
- 즉, 다음 스텝으로의 전환을 위해 ==CSS는 완전히 구문이 분석되어야 한다.== 그렇기에 이는 Rendering Blocking resource 이자 Script Blocking resource이기도 하다.
- media 속성과 같은 경우에 따라 Rendering Blocking으로 이어지지 않는 경우도 있다. (orientation:landscape-가로모드로 설정된 상황에서 페이지를 세로 모드로 보고있더라도 Rendering이 차단되지 않는다.)
3. Running JavaScript
- JavaScript는 'parser Blocking Resource' 로 간주된다.
- HTML문서 자체의 구문 분석이 JavaScript에 의해 차단되기 때문
- parser가 \<script> tag에 도달하게 된다면 fetch를 중단하고, script를 실행하게 됩니다. 그렇기에 이러한 요소들은 우리가 JavaScript 참조 엘리먼트를 문서의 마지막에 두어야 하는 이유가 되기도 합니다.
- JavaScript가 parser blocking으로서 작동되기를 원하지 않는다면. 비동기(async) 속성을 부여하여 적용할 수 있습니다.
4. Creating the Render Tree
- Render Tree : DOM + CSSOM
- 페이지에 렌더링 될 항목을 나타내는 Tree
- 즉, 보이는 컨테츠만 추린다.(CSS로 숨겨진 요소 미포함, display:none ...)

5. Generating the Layout
- viewport 의 크기를 결정
- 백분율, 뷰포트 단위와 같이 레이아웃에 의존하는 CSS 스타일에 대한 컨텍스트 제공
- 문서 헤드에 제공된 메타 뷰포트 태그에 의해 결정 혹은 태그가 제공되지 않은 경우 기본 뷰포트 너비인 980px가 사용된다.
가장 일반적인 메타 viewport값은 장치 너비에 해당하는 뷰포트의 크기이다.
<meta name="viewport" content="width=device-width,initial-scale=1">
6. Painting
- 페이지의 보이는 콘텐츠 -> 픽셀로 변환
- 이 단계에서 그라이데션과 같은 배경 이미지는 더 많은 시간을 필요로 한다.
Putting it All Together
진행 중인 렌더링 경로 확인
<html>
<head>
<title>Understanding the Critical Rendering Path</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<header>
<h1>Understanding the Critical Rendering Path</h1>
</header>
<main>
<h2>Introduction</h2>
<p>Lorem ipsum dolor sit amet</p>
</main>
<footer>
<small>Copyright 2017</small>
</footer>
<script src="main.js"></script>
</body>
</html>
- 이벤트 로그(DevTools)

- Send Request - index.html에 대해 보낸 GET request
- Parse HTML & Send Request(HTML 구문 분석(Parse HTML) 및 Send Request) - HTML 및 DOM 구성의 구문 분석 시작. style.css, main.js에 대한 GET 요청 보내기
- Parse Stylessheet(구문 분석 스타일시트) - style.css용으로 생성된 CSSOM
- Evaluate Script(스크립트 평가) - main.js 평가
- Layout(레이아웃) - HTML 태그 중 meta tag의 viewport에 기반한 Layout 생성
- Paint(페인트) - pixel로 변환
결론
이와 같은 지식을 기반으로 우린 어떻게 Critical Rendering Path의 최적화를 적용할지 결정할 수 있다.
참고
https://bitsofco.de/understanding-the-critical-rendering-path/