성능 관찰자 - 성능 데이터에 효율적으로 액세스

마크 코헨

프로그레시브 웹 앱을 사용하면 개발자는 안정적이고 고성능의 사용자 환경을 제공하는 새로운 유형의 애플리케이션을 빌드할 수 있습니다. 하지만 웹 앱이 원하는 성능 목표를 달성하려면 개발자가 고해상도 성능 측정 데이터에 액세스해야 합니다. W3C 성능 타임라인 사양은 브라우저가 하위 수준의 타이밍 데이터에 프로그래매틱 방식으로 액세스할 수 있도록 하는 이러한 인터페이스를 정의합니다. 이를 통해 몇 가지 흥미로운 사용 사례가 열립니다.

  • 오프라인 및 커스텀 성능 분석
  • 서드 파티 성능 분석 및 시각화 도구
  • IDE 및 기타 개발자 도구에 통합된 성능 평가

탐색 타이밍, 리소스 타이밍, 사용자 시간에 대해 이미 대부분의 주요 브라우저에서 이러한 종류의 타이밍 데이터에 액세스할 수 있습니다. 최근에 추가된 성능 관찰자 인터페이스가 추가되었습니다. 이 인터페이스는 기본적으로 브라우저에서 수집하는 낮은 수준의 타이밍 정보를 비동기식으로 수집하는 스트리밍 인터페이스입니다. 이 새로운 인터페이스는 타임라인에 액세스하는 이전 방법에 비해 여러 가지 중요한 이점을 제공합니다.

  • 오늘날 앱은 저장된 측정을 주기적으로 폴링하고 비교해야 하므로 비용이 많이 듭니다. 이 인터페이스에서 콜백을 제공합니다. 즉, 폴링할 필요가 없습니다. 따라서 이 API를 사용하는 앱의 응답성과 효율성이 향상됩니다.
  • 버퍼 제한은 적용되지 않으며 (대부분의 버퍼는 기본적으로 150개 항목으로 설정됨), 버퍼를 수정하려는 여러 소비자 간의 경합 상태를 방지합니다.
  • 성능 관찰자 알림은 비동기식으로 전달되며 브라우저는 유휴 시간에 알림을 전달하여 중요한 렌더링 작업과 경쟁하지 않도록 할 수 있습니다.

Chrome 52부터 성능 관찰자 인터페이스가 기본적으로 사용 설정됩니다. 사용 방법을 살펴보겠습니다.

<html>
<head>
    <script>
    var observer = new PerformanceObserver(list => {
        list.getEntries().forEach(entry => {
        // Display each reported measurement on console
        if (console) {
            console.log("Name: "       + entry.name      +
                        ", Type: "     + entry.entryType +
                        ", Start: "    + entry.startTime +
                        ", Duration: " + entry.duration  + "\n");
        }
        })
    });
    observer.observe({entryTypes: ['resource', 'mark', 'measure']});
    performance.mark('registered-observer');

    function clicked(elem) {
        performance.measure('button clicked');
    }
    </script>
</head>
<body>
    <button onclick="clicked(this)">Measure</button>
</body>
</html>

이 간단한 페이지는 몇 가지 자바스크립트 코드를 정의하는 스크립트 태그로 시작합니다.

  • 새로운 PerformanceObserver 객체를 인스턴스화하고 이벤트 핸들러 함수를 객체 생성자에 전달합니다. 생성자는 새 측정 데이터 세트를 처리할 준비가 될 때마다 (측정 데이터가 객체 목록으로 전달됨) 핸들러가 호출되도록 객체를 초기화합니다. 여기서 핸들러는 콘솔에 형식이 지정된 측정 데이터를 단순히 표시하는 익명 함수로 정의됩니다. 실제 시나리오에서 이 데이터는 후속 분석을 위해 클라우드에 저장되거나 대화형 시각화 도구로 파이핑될 수 있습니다.
  • observe() 메서드를 통해 관심 있는 타이밍 이벤트 유형에 등록하고 mark() 메서드를 호출하여 타이밍 간격의 시작으로 간주할 등록 시점을 표시합니다.
  • 페이지 본문에 정의된 버튼의 클릭 핸들러를 정의합니다. 이 클릭 핸들러는 measure() 메서드를 호출하여 버튼 클릭 시점에 관한 타이밍 데이터를 캡처합니다.

페이지 본문에서 버튼을 정의하고 클릭 핸들러를 onclick 이벤트에 할당하면 준비를 마칠 수 있습니다.

이제 페이지를 로드하고 Chrome DevTools 패널을 열어 JavaScript 콘솔을 보면 버튼을 클릭할 때마다 성능을 측정합니다. 또한 이러한 측정값을 관찰하도록 등록했으므로 타임라인을 폴링할 필요 없이 이벤트 핸들러에 비동기식으로 전달되며 이벤트 핸들러에 측정값이 표시됩니다.

성능 관찰자입니다.

start 값은 mark 유형 이벤트 (이 앱에는 이 중에 하나만 있음)의 시작 타임스탬프를 나타냅니다. 유형이 measure인 이벤트에는 고유한 시작 시간이 없습니다. 즉, 마지막 mark 이벤트를 기준으로 실행된 타이밍 측정을 나타냅니다. 따라서 여기에 표시된 시간 값은 공통 간격 시작점 역할을 하는 mark() 호출과 measure()의 여러 후속 호출 사이에 경과된 시간을 나타냅니다.

보시다시피 이 API는 매우 간단하며 폴링 없이 필터링된 고해상도 실시간 성능 데이터를 수집할 수 있는 기능을 제공하므로 웹 앱을 위한 보다 효율적인 성능 도구를 사용할 수 있습니다.