중요 렌더링 경로 최적화

김장남·2022년 2월 2일
2

Browser Rendering

목록 보기
3/5
post-thumbnail

중요 렌더링 경로

Critical Rendering Path

주요 렌더링 경로란
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를 사용 하면 쉽게 볼 수 있습니다. (그 방법은 필요하신 분 있으면 나중에 정리 해 드릴게욤)

그럼 차근차근 하나씩 따져봅시다.

1. HTML + Image

<!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 된다는 점

이미지는 초기 렌더링을 방해하지 않지만 그래도 최대한 빨리 그려주어야 합니다.

2. HTML + Image + 외부 CSS + 외부 Script

<!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 요소를 필요에 따라 나눈다면 성능 패턴은 아래와 같습니다.

성능패턴

3. HTML + Image + 인라인 CSS + 인라인 Script

<!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로 만들었다간..문제가 생기겠죠?)


여기까지 너무 많은 글을 적어 좀 죄송하지만 아직 끝난게 아닙니다.
다음글은 드디어 의문을 갖고 그 의문을 해결하는 과정을 정리 할 겁니다.
ㅜㅜ
( 적는거 생각보다 시간도 많이들어가고 공부도 더 자세히 하게 되네요)

예고편: 아니 DOM/CSSOM 파싱하고 Render Tree만들어서 Layout하고 Paint 한다매!!!

profile
React 개발자

0개의 댓글