주요 렌더링 경로란
DOM 파싱 부터 렌더까지의 경로를 말한다.
주요 프로세스
- domLoading: 전체 프로세스의 시작 타임스탬프입니다. 브라우저가 처음 수신한 HTML 문서 바이트의 파싱을 시작하려고 합니다.
- domInteractive: 브라우저가 파싱을 완료한 시점을 표시합니다. 모든 HTML 및 DOM 생성 작업이 완료되었습니다.
- domContentLoaded: DOM이 준비되고 자바스크립트 실행을 차단하는 스타일시트가 없는 시점을 표시합니다. 즉, 이제 (잠재적으로) 렌더링 트리를 생성할 수 있습니다.
많은 자바스크립트 프레임워크가 자체 로직을 실행하기 전에 이 이벤트를 기다립니다. 이러한 이유로 브라우저는 EventStart 및 EventEnd 타임스탬프를 캡처합니다. 이를 통해 이 실행이 얼마나 오래 걸렸는지 추적할 수 있습니다.- domComplete: 이름이 의미하는 바와 같이, 모든 처리가 완료되고 페이지의 모든 리소스(이미지 등) 다운로드가 완료되었습니다( 예: 로딩 스피너가 회전을 멈춤).
- loadEvent: 각 페이지 로드의 최종 단계로, 브라우저가 추가 애플리케이션 로직을 트리거할 수 있는 onload 이벤트를 발생시킵니다.
HTML 사양은 이벤트가 발생하는 시기, 충족해야 하는 조건 등 각 이벤트에 대한 특정 조건을 규정합니다. 여기서는 주요 렌더링 경로와 관련된 몇 가지 주요 마일스톤을 중점적으로 살펴보겠습니다.
- domInteractive는 DOM이 준비된 시점을 표시합니다.
- domContentLoaded는 일반적으로 DOM 및 CSSOM이 모두 준비된 시점을 표시합니다.
파서 차단 자바스크립트가 없으면 domInteractive 직후에 DOMContentLoaded가 발생할 것입니다.- domComplete는 페이지 및 해당 하위 리소스가 모두 준비된 시점을 표시합니다
경로를 측정 하는것은 Chrome Devtool의 LightHouse, perfomance를 사용 하면 쉽게 볼 수 있습니다. (그 방법은 필요하신 분 있으면 나중에 정리 해 드릴게욤)
그럼 차근차근 하나씩 따져봅시다.
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width,initial-scale=1">
<title>Critical Path: No Style</title>
</head>
<body>
<p>Hello <span>web performance</span> students!</p>
<div><img src="awesome-photo.jpg"></div>
</body>
</html>
성능 패턴
파란 줄이 DOMContentLoaded(DCL) 빨간줄이 onLoad(L) 입니다.
html을 받아오는데 205ms가 소요됐고 216ms에 DCL이벤트가 발생했고 이미지를 받아오는데 118ms가 소요됐고 335ms에 L이 발생했습니다.
여기서 알 수 있는 점은 Image 다운로드는 Parser를 blocking 하지 않는다는것,
하지만 onLoad 이벤트는 Image에 의해 blocking 된다는 점
이미지는 초기 렌더링을 방해하지 않지만 그래도 최대한 빨리 그려주어야 합니다.
<!DOCTYPE html>
<html>
<head>
<title>Critical Path: Measure Script</title>
<meta name="viewport" content="width=device-width,initial-scale=1">
<link href="style.css" rel="stylesheet">
</head>
<body onload="measureCRP()">
<p>Hello <span>web performance</span> students!</p>
<div><img src="awesome-photo.jpg"></div>
<script src="timing.js"></script>
</body>
</html>
성능패턴
CSS와 Javascript를 받아오는 네트워크 요청이 2개 더 생겼습니다.
앞서 배운대로 CSS와 Javascript는 Parser를 Blocking 하여 DCL을 늦춥니다.
그럼 여기서 script에 async를 넣으면 어떻게 될 까요?
성능패턴
Parser를 Block하지 않기 때문에 DCL은 DOM이 로드되고 거의 바로 발생합니다. L이 발생하는 시기는 차이가 없습니다.
추가적으로 Media Query를 사용하여 CSS 요소를 필요에 따라 나눈다면 성능 패턴은 아래와 같습니다.
성능패턴
<!DOCTYPE html>
<html>
<head>
<title>Critical Path: Measure Inlined</title>
<meta name="viewport" content="width=device-width,initial-scale=1">
<style>
p { font-weight: bold }
span { color: red }
p span { display: none }
img { float: right }
</style>
</head>
<body>
<p>Hello <span>web performance</span> students!</p>
<div><img src="awesome-photo.jpg"></div>
<script>
var span = document.getElementsByTagName('span')[0];
span.textContent = 'interactive'; // change DOM text content
span.style.display = 'inline'; // change CSSOM property
// create a new element, style it, and append it to the DOM
var loadTime = document.createElement('div');
loadTime.textContent = 'You loaded this page on: ' + new Date();
loadTime.style.color = 'blue';
document.body.appendChild(loadTime);
</script>
</body>
</html>
HTML의 크기는 커졌지만 로드할 요소들이 존재하지 않아 DCL은 HTML로드 후 바로 발생 합니다. (예제에서는 CSS와 Script가 간단하여 문제가 없지만 실제로는 하나의 HTML로 만들었다간..문제가 생기겠죠?)
여기까지 너무 많은 글을 적어 좀 죄송하지만 아직 끝난게 아닙니다.
다음글은 드디어 의문을 갖고 그 의문을 해결하는 과정을 정리 할 겁니다. ㅜㅜ
( 적는거 생각보다 시간도 많이들어가고 공부도 더 자세히 하게 되네요)