게시일: 2014년 3월 31일
모든 탄탄한 성능 전략은 훌륭한 측정과 계측을 바탕으로 합니다. 측정할 수 없는 사항을 최적화할 수 없습니다. 이 가이드에서는 CRP 실적을 측정하는 다양한 접근 방식을 설명합니다.
- Lighthouse 접근방식에서는 일련의 자동화된 테스트를 페이지에 실행한 다음, 페이지의 CRP 성능에 대한 보고서를 생성합니다. 이 접근 방식은 브라우저에 로드된 특정 페이지의 CRP 성능을 쉽고 빠르게 측정해 주며, 신속하게 테스트를 수행하고 반복하여 성능을 개선해 줍니다.
- Navigation Timing API 접근방식에서는 RUM (실시간 사용자 모니터링) 측정항목을 캡처합니다. 이름에서 알 수 있듯이, 이 지표는 실제 사용자의 사이트 상호작용으로부터 캡처되며, 다양한 기기와 네트워크 조건에서 사용자가 경험하는 실제 CRP 성능을 정확하게 보여줍니다.
일반적인 좋은 접근방식은 Lighthouse를 사용하여 명백한 CRP 최적화 기회를 파악한 다음 Navigation Timing API로 코드를 작성하여 앱의 실제 성능을 모니터링하는 것입니다.
Lighthouse로 페이지 감사
Lighthouse는 웹 앱 감사 도구이며 해당 페이지에 대해 일련의 테스트를 수행한 다음, 이 페이지의 결과를 통합된 보고서로 표시해줍니다. Lighthouse를 Chrome 확장 프로그램이나 NPM 모듈로 실행할 수 있으며, 이는 Lighthouse와 지속적 통합 시스템을 통합하는 데 유용합니다.
시작하려면 Lighthouse로 웹 앱 감사를 참고하세요.
Lighthouse를 Chrome 확장 프로그램으로 실행하면 페이지의 CRP 결과는 다음 스크린샷과 같이 표시됩니다.
이 감사의 결과에 대한 자세한 내용은 주요 요청 체인을 참고하세요.
Navigation Timing API로 코드 계측
Navigation Timing API와 기타 여러 브라우저 이벤트를 조합해서 사용하여 페이지가 로드될 때 발생하는 이벤트를 통해 임의 페이지의 실제 CRP 성능을 캡처하고 기록할 수 있습니다.
이전 다이어그램의 각 레이블은 로드되는 각각의 모든 페이지에 대해 브라우저가 추적하는 고해상도 타임스탬프에 해당합니다. 사실상, 이 특정 경우에서는 다양한 모든 타임스탬프 중 일부만 보여줍니다. 지금은 모든 네트워크 관련 타임스탬프를 건너뛰지만 이후 과정에서 이에 대해 다시 살펴볼 것입니다.
그렇다면 이러한 타임스탬프가 의미하는 바는 무엇일까요?
domLoading
: 전체 프로세스의 시작 타임스탬프입니다. 브라우저가 처음 수신한 HTML 문서 바이트의 파싱을 시작하려고 합니다.domInteractive
: 브라우저가 파싱을 완료한 시점을 표시합니다. 모든 HTML 및 DOM 생성 작업이 완료되었습니다.domContentLoaded
: DOM이 준비되고 자바스크립트 실행을 차단하는 스타일시트가 없는 시점을 표시합니다. 즉, 이제 (잠재적으로) 렌더링 트리를 생성할 수 있습니다.- 많은 JavaScript 프레임워크가 자체 로직을 실행하기 전에 이 이벤트를 기다립니다. 이러한 이유로 브라우저는
EventStart
및EventEnd
타임스탬프를 캡처합니다. 이를 통해 이 실행이 얼마나 오래 걸렸는지 추적할 수 있습니다.
- 많은 JavaScript 프레임워크가 자체 로직을 실행하기 전에 이 이벤트를 기다립니다. 이러한 이유로 브라우저는
domComplete
: 이름이 의미하는 바와 같이, 모든 처리가 완료되고 페이지의 모든 리소스 (이미지 등) 다운로드가 완료되었습니다. 즉, 로딩 스피너가 회전을 멈춤loadEvent
: 각 페이지 로드의 최종 단계로, 브라우저가 추가 애플리케이션 로직을 트리거할 수 있는onload
이벤트를 발생시킵니다.
HTML 사양은 이벤트가 발생하는 시기, 충족해야 하는 조건, 기타 중요한 고려사항 등 각 이벤트에 대한 특정 조건을 규정합니다. 여기서는 주요 렌더링 경로와 관련된 몇 가지 주요 마일스톤을 중점적으로 살펴보겠습니다.
domInteractive
는 DOM이 준비된 시점을 표시합니다.domContentLoaded
는 일반적으로 DOM과 CSSOM이 모두 준비된 시점을 표시합니다.- JavaScript를 차단하는 파서가 없으면
domInteractive
직후에DOMContentLoaded
가 실행됩니다.
- JavaScript를 차단하는 파서가 없으면
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는 모든 관련 타임스탬프를 캡처하고 개발자 코드는 onload
이벤트가 발생하기를 기다립니다. onload
이벤트는 domInteractive
, domContentLoaded
, domComplete
이후에 발생한다는 사실을 상기하세요. 또한 이 API는 다양한 타임스탬프 간의 차이를 계산합니다.
모든 것이 말한대로 이루어졌으면, 이제 측정할 몇 가지 특정한 마일스톤과 이러한 측정 결과를 출력하기 위한 기본 함수가 만들어졌을 것입니다. 이러한 측정항목을 페이지에 출력하는 대신 코드를 수정하여 이러한 측정항목을 분석 서버로 전송할 수도 있습니다 (Google 애널리틱스에서 자동으로 처리). 이는 페이지의 실적을 계속 확인하고 최적화 작업의 이점을 누릴 수 있는 후보 페이지를 식별하는 데 유용한 방법입니다.
DevTools는 어떨까요?
이 문서에서는 CRP 개념을 설명하기 위해 Chrome DevTools Network 패널을 사용하기도 하지만 DevTools는 주요 리소스를 분리하기 위한 내장 메커니즘이 없기 때문에 CRP 측정에 적합하지 않습니다. 이러한 리소스를 식별하도록 도우려면 Lighthouse 감사를 실행하세요.