주요 렌더링 경로 측정

Ilya Grigorik
Ilya Grigorik

모든 탄탄한 성능 전략은 훌륭한 측정과 계측을 기반으로 합니다. 측정할 수 없는 것은 최적화할 수 없습니다. 이 문서에서는 CRP 성능을 측정하는 다양한 접근 방식을 설명합니다.

  • Lighthouse 접근 방식은 페이지에 대해 일련의 자동화된 테스트를 실행한 다음 페이지의 CRP 성능에 관한 보고서를 생성합니다. 이 접근 방식을 사용하면 브라우저에 로드된 특정 페이지의 CRP 성능을 빠르고 쉽게 개략적으로 파악할 수 있으므로 빠르게 테스트하고 반복하며 성능을 개선할 수 있습니다.
  • Navigation Timing API 방식은 RUM (Real User Monitoring) 측정항목을 캡처합니다. 이름에서 알 수 있듯이 이러한 측정항목은 사이트와의 실제 사용자 상호작용에서 캡처되며 다양한 기기와 네트워크 조건에서 사용자가 경험하는 실제 CRP 성능을 정확하게 보여줍니다.

일반적으로 좋은 접근 방식은 Lighthouse를 사용하여 명확한 CRP 최적화 기회를 파악한 다음 Navigation Timing API로 코드를 계측하여 앱의 실제 성능을 모니터링하는 것입니다.

Lighthouse로 페이지 감사하기

Lighthouse는 특정 페이지를 대상으로 일련의 테스트를 실행한 후 페이지의 결과를 통합된 보고서에 표시하는 웹 앱 감사 도구입니다. Lighthouse를 Chrome 확장 프로그램 또는 NPM 모듈로 실행할 수 있습니다. 이는 Lighthouse를 지속적 통합 시스템과 통합하는 데 유용합니다.

시작하려면 Lighthouse로 웹 앱 감사를 참조하세요.

Lighthouse를 Chrome 확장 프로그램으로 실행하면 페이지 CRP 결과가 아래 스크린샷과 같이 표시됩니다.

Lighthouse의 CRP 감사

이 감사의 결과에 대한 자세한 내용은 중요 요청 체인을 참조하세요.

Navigation Timing API와 페이지 로드 시 발생하는 기타 브라우저 이벤트를 함께 사용하면 모든 페이지의 실제 CRP 성능을 캡처하고 기록할 수 있습니다.

Navigation Timing

위 다이어그램의 각 라벨은 로드되는 모든 페이지에 대해 브라우저가 추적하는 고해상도 타임스탬프에 해당합니다. 실제로 이 특정 사례에서는 다양한 타임스탬프 중 일부만 표시합니다. 지금은 네트워크 관련 타임스탬프를 모두 건너뛰지만 이후 과정에서 다시 살펴보겠습니다.

그렇다면 이러한 타임스탬프는 무엇을 의미할까요?

  • domLoading: 전체 프로세스의 시작 타임스탬프입니다. 브라우저가 HTML 문서의 첫 번째 수신된 바이트를 파싱하기 시작합니다.
  • domInteractive: 브라우저에서 모든 HTML 및 DOM 생성이 완료된 파싱을 완료한 지점을 표시합니다.
  • domContentLoaded: DOM이 모두 준비되고 JavaScript 실행을 차단하는 스타일시트가 없는 지점을 표시합니다. 즉, 이제 렌더링 트리를 생성할 수 있습니다.
    • 많은 JavaScript 프레임워크는 자체 로직을 실행하기 전에 이 이벤트를 기다립니다. 따라서 브라우저는 EventStartEventEnd 타임스탬프를 캡처하여 이 실행이 얼마나 걸렸는지 추적할 수 있습니다.
  • domComplete: 이름에서 알 수 있듯이 모든 처리가 완료되고 페이지의 모든 리소스 (이미지 등) 다운로드가 완료되었습니다. 즉, 로딩 스피너가 회전을 중지했습니다.
  • loadEvent: 모든 페이지 로드의 마지막 단계로, 브라우저에서 추가 애플리케이션 로직을 트리거할 수 있는 onload 이벤트를 실행합니다.

HTML 사양은 이벤트가 실행되는 시점, 충족해야 하는 조건 등 각 이벤트에 대한 특정 조건을 지정합니다. 여기서는 주요 렌더링 경로와 관련된 몇 가지 주요 마일스톤을 중점적으로 살펴보겠습니다.

  • domInteractive는 DOM이 준비된 시점을 표시합니다.
  • domContentLoaded는 일반적으로 DOM 및 CSSOM이 모두 준비된 시점을 표시합니다.
    • 파서 차단 자바스크립트가 없으면 domInteractive 직후에 DOMContentLoaded가 실행됩니다.
  • domComplete는 페이지 및 페이지의 모든 하위 리소스가 준비되었음을 표시합니다.
<!DOCTYPE html>
<html>
  <head>
    <title>Critical Path: Measure</title>
    <meta name="viewport" content="width=device-width,initial-scale=1" />
    <link href="style.css" rel="stylesheet" />
    <script>
      function measureCRP() {
        var t = window.performance.timing,
          interactive = t.domInteractive - t.domLoading,
          dcl = t.domContentLoadedEventStart - t.domLoading,
          complete = t.domComplete - t.domLoading;
        var stats = document.createElement('p');
        stats.textContent =
          'interactive: ' +
          interactive +
          'ms, ' +
          'dcl: ' +
          dcl +
          'ms, complete: ' +
          complete +
          'ms';
        document.body.appendChild(stats);
      }
    </script>
  </head>
  <body onload="measureCRP()">
    <p>Hello <span>web performance</span> students!</p>
    <div><img src="awesome-photo.jpg" /></div>
  </body>
</html>

사용해 보기

위의 예는 첫 눈에는 다소 벅차게 보일 수 있지만 실제로는 매우 간단합니다. Navigation Timing API는 모든 관련 타임스탬프를 캡처하고 Google 코드는 단순히 onload 이벤트가 실행될 때까지 대기합니다. onload 이벤트는 domInteractive, domContentLoaded, domComplete 이후에 발생한다는 점을 기억하세요. 그런 다음 다양한 타임스탬프 간의 차이를 계산합니다.

NavTiming 데모

모두 마쳤으므로 이제 추적해야 할 몇 가지 특정 마일스톤과 이러한 측정값을 출력하는 간단한 함수가 준비되었습니다. 이러한 측정항목을 페이지에 출력하는 대신 코드를 수정하여 분석 서버로 이러한 측정항목을 전송할 수도 있습니다 (Google 애널리틱스에서는 자동으로 이 작업을 실행). 이렇게 하면 페이지 실적을 지속적으로 확인하고 최적화 작업을 통해 실적을 높일 수 있는 후보 페이지를 파악할 수 있습니다.

DevTools는 어떤가요?

이 문서에서는 Chrome DevTools 네트워크 패널을 사용하여 CRP 개념을 설명하는 경우도 있지만 현재 DevTools는 CRP 측정에 적합하지 않습니다. 중요한 리소스를 격리하는 메커니즘이 내장되어 있지 않기 때문입니다. 이러한 리소스를 식별하는 데 도움이 되도록 Lighthouse 감사를 실행합니다.

의견