Chrome DevTools 성능 패널을 사용하여 Angular 앱 프로파일링

Andrés Olivares
Andrés Olivares
Pawel Kozlowski
Pawel Kozlowski

Angular, React, Vue, Svelte와 같은 웹 프레임워크를 사용하면 복잡한 웹 애플리케이션을 대규모로 더 쉽게 작성하고 유지관리할 수 있습니다.

하지만 이러한 프레임워크는 브라우저의 애플리케이션 모델 위에 추상화 계층을 도입합니다. 실제로 이러한 추상화를 사용하는 개발자가 작성한 코드는 일반적으로 읽을 수 없고 축소되고 번들로 묶인 코드로 트랜스파일됩니다. 따라서 개발자가 DevTools의 기능을 최대한 활용하여 이러한 앱을 디버그하고 프로파일링하기 어려울 수 있습니다.

예를 들어 DevTools의 성능 패널로 Angular 애플리케이션을 프로파일링하면 다음과 같이 표시됩니다.

Angular 앱에서 가져온 페이지 로드의 타임라인을 보여주는 성능 패널 트레이스 뷰입니다. 축소된 이름이 있는 JavaScript 호출의 플레임차트를 보여주는 확장된 기본 스레드 스윔레인에 초점을 맞춥니다.
성능 패널 트레이스 보기

이러한 방식으로 정보가 표시되면 코드베이스에 어떤 성능 병목 현상이 있는지 파악하기 어려울 수 있습니다. 프레임워크 구조의 컨텍스트가 누락되어 있고 표시된 정보의 상당 부분이 축소된 코드 형식이기 때문입니다. 또한 작성한 코드와 직접 관련된 활동, 프레임워크 내부, 동일한 페이지에서 실행될 수 있는 기타 서드 파티 코드를 구분하기 어렵습니다.

프레임워크 및 추상화 작성자의 일반적인 동기는 프레임워크 개념 측면에서 프로파일링 데이터를 표시하는 자체 DevTools 확장 프로그램을 구현하는 것입니다. 이러한 도구는 특정 프레임워크로 빌드된 애플리케이션을 디버깅하고 프로파일링할 때 매우 유용합니다. 하지만 프레임워크 자체 프로파일러의 프레임워크 데이터를 DevTools 성능 패널의 브라우저 런타임 정보와 상호 연관시켜야 하는 경우가 더 많습니다. 이러한 두 데이터 소스가 독립적인 도구에 별도로 표시되면 특히 애플리케이션이 복잡해질수록 병목 현상을 파악하고 수정하기가 어려워집니다. 다음은 Angular DevTools 프로파일러의 프로필 시각화 예시입니다.

Angular DevTools의 프로파일러 탭에 Angular 앱의 런타임에 관한 Flame 그래프가 표시되어 있습니다. Flame 그래프를 구성하는 항목에는 Angular 구성요소 이름을 연상시키는 읽기 쉬운 라벨이 있습니다.
Angular DevTools 프로파일러입니다.

이상적인 상황은 개발자가 동일한 타임라인에 매핑된 동일한 컨텍스트에 두 데이터 소스가 함께 표시되는 뷰를 갖는 것입니다.

이러한 이유로 Angular팀과 협력하여 성능 패널 확장성 API를 사용하여 Angular 런타임 데이터를 성능 패널로 바로 가져왔습니다. 이 게시물에서는 API가 할 수 있는 작업과 Angular 프레임워크에서 이를 달성하기 위해 API가 어떻게 사용되었는지 살펴봅니다. 이 구현은 자체 도구를 계측하고 Chrome DevTools를 사용하는 개발자를 지원하여 개발자 환경을 개선하려는 다른 프레임워크와 추상화의 예가 될 수 있습니다.

성능 패널 확장 가능성 API란 무엇인가요?

이 API를 사용하면 나머지 브라우저 데이터와 동일한 타임라인 내에서 성능 패널 트레이스에 자체 타이밍 항목을 추가할 수 있습니다. 이를 지원하는 두 가지 메커니즘이 있습니다.

  • User Timing API
  • console.timeStamp API

User Timing API

performance.markperformance.measure를 사용하여 다음과 같이 항목을 추가할 수 있습니다.


// Mark used to represent the start of some activity you want to measure.
// In this case, the rendering of a component.
const renderStart = performance.now();

// ... later in your code

performance.measure("Component rendering", {
  start: renderStart,
  detail: {
    devtools: {
      dataType: "track-entry",
      track: "Components",
      color: "secondary",
      properties: [
        ["Render reason", "Props changed"],
        ["Priority", "low"]
      ],
    }
  }
});

이렇게 하면 측정과 함께 구성요소 트랙이 타임라인에 추가됩니다.

성능 패널 추적 보기 '구성요소 렌더링'이라는 측정항목이 포함된 '구성요소'라는 확장된 맞춤 트랙에 중점을 둡니다.
성능 패널의 맞춤 트랙

이 API를 사용하면 성능 타임라인 버퍼에 항목을 추가하는 동시에 DevTools 성능 패널 UI에 항목을 표시할 수 있습니다.

문서에서 이 API와 devtools 객체에 대해 자세히 알아보세요.

console.timeStamp API

이 API는 User Timing API의 경량화된 대안입니다. 이전과 동일한 예시를 사용하면 다음과 같이 표시됩니다.


// Mark used to represent the start of some activity you want to measure.
// In this case, the rendering of a component.
const renderStart = performance.now();

// ... later in your code

console.timeStamp(
"Component rendering",
/* start time */ renderStart,
/* end time (current time) */ undefined,
/* track name */ "Components",
 /* track group name */ undefined,
 /* color */ "secondary"
);

이 API는 애플리케이션을 계측하는 고성능 방법을 제공합니다. User Timing API 대안과 달리 버퍼링된 데이터를 생성하지 않습니다. 이 API는 DevTools의 **성능** 패널에만 데이터를 추가합니다. 즉, DevTools가 트레이스를 기록하지 않을 때 API 호출은 아무 작업도 하지 않으므로 성능에 민감한 핫 경로에 적합하며 훨씬 빠릅니다. 모든 맞춤설정 매개변수가 포함된 객체 대신 위치 인수 사용을 선택하는 것도 API를 최대한 가볍게 유지하기 위한 것입니다.

console.timeStamp를 사용하여 성능 패널을 확장하는 방법과 문서에서 전달할 수 있는 매개변수에 대해 자세히 알아보세요.

Angular에서 DevTools 확장 가능성 API를 통합한 방법

Angular 팀이 확장성 API를 사용하여 Chrome DevTools와 통합한 방법을 살펴보겠습니다.

console.timestamp로 오버헤드 방지

성능 패널 확장성 API를 사용한 Angular의 계측은 버전 20부터 사용할 수 있습니다. DevTools에서 원하는 성능 데이터의 세부사항 수준에는 빠른 API가 필요하므로 계측을 추가한 풀 요청 (60217)에서는 console.timeStamp API를 사용하기로 했습니다. 이렇게 하면 프로파일링 API의 잠재적 오버헤드가 애플리케이션 런타임 성능에 영향을 미치지 않습니다.

계측된 데이터

Angular 코드가 실행되는 방식과 실행되는 이유를 잘 파악할 수 있도록 시작 및 렌더링 파이프라인의 여러 부분이 계측됩니다.

  • 애플리케이션 및 구성요소 부트스트랩
  • 구성요소 생성 및 업데이트
  • 이벤트 리스너 및 수명 주기 후크 실행
  • 기타 여러 기능 (예: 동적 구성요소 생성, 블록 렌더링 지연)

색상 코딩

색상 코딩은 특정 측정 항목이 속하는 카테고리를 개발자에게 알리는 데 사용됩니다. 예를 들어 개발자가 작성한 TypeScript 코드의 실행을 표시하는 항목에 사용되는 색상은 Angular 컴파일러에서 생성된 코드에 사용되는 색상과 다릅니다.

다음 스크린샷에서는 이로 인해 진입점 (예: 변경 감지 및 구성요소 처리)이 파란색으로, 생성된 코드가 보라색으로, TypeScript 코드 (예: 이벤트 리스너 및 후크)가 녹색으로 렌더링되는 방식을 확인할 수 있습니다.

성능 패널 추적 보기 개발자 친화적인 방식으로 Angular 앱의 런타임 활동을 나타내는 다양한 색상의 측정값이 포함된 플레임차트가 포함된 'Angular'라는 확장된 맞춤 트랙에 중점을 둡니다.
성능 패널의 색상 분류

API에 전달된 color argument는 CSS 색상 값이 아니라 DevTools UI와 일치하는 색상에 매핑된 시맨틱 토큰입니다. 가능한 값은 primary, secondary, tertiary,이며 각각 -dark-light 변형과 error 색상도 있습니다.

트랙

작성 시점에는 모든 Angular 런타임 데이터가 동일한 트랙('🅰️ Angular' 라벨이 지정됨)에 추가됩니다. 하지만 트레이스에 트랙을 여러 개 추가하고 트랙을 그룹화할 수도 있습니다. 예를 들어 console.timeStamp API에 대한 다음 호출이 있다고 가정해 보겠습니다.

console.timeStamp("Component 1", componentStart1, componentEnd1, "Components", "Client", "primary");
console.timeStamp("Component 2", componentStart2, componentEnd2, "Components", "Client", "primary");
console.timeStamp("Hook 1", hookStart, hookEnd, "Hooks", "Client", "primary");
console.timeStamp("Fetch data base", fetchStart, fetchEnd, "Server", "primary");

다음과 같이 트랙에 데이터가 정리되어 표시됩니다.

성능 패널 추적 보기 내부에 서로 다른 측정값이 있는 여러 개의 확장된 맞춤 트랙에 중점을 둡니다.
성능 패널의 여러 맞춤 트랙

별도의 트랙을 사용하는 것은 비동기 활동이 있거나, 여러 작업이 병렬로 실행되거나, UI의 서로 다른 영역에서 분리할 가치가 있을 만큼 활동 그룹이 충분히 구별되는 경우에 유용할 수 있습니다.

Angular 개발자에게 중요한 이유

이 직접 통합의 목표는 더욱 직관적이고 포괄적인 실적 분석 환경을 제공하는 것입니다. **성능** 패널 내에서 직접 Angular의 내부 성능 데이터를 표시하면 개발자는 다음을 얻을 수 있습니다.

  • 가시성 향상: 구성요소 렌더링, 변경 감지 주기 등 Angular 관련 성능 이벤트를 더 광범위한 브라우저 타임라인 내에서 표시합니다.
  • 이해도 향상: Angular의 내부 프로세스에 관한 풍부한 컨텍스트 정보를 제공하여 성능 병목 현상을 더 효과적으로 파악할 수 있습니다.

통합 사용 설정

확장성 API의 사용은 Angular 버전 20부터 개발 빌드에서 공식적으로 지원됩니다. 이를 사용 설정하려면 앱 또는 DevTools 콘솔에서 전역 유틸리티 `ng.enableProfiling()` 을 실행해야 합니다. 통합에 대한 자세한 내용은 [Angular 문서](https://angular.dev/best-practices/profiling-with-chrome-devtools)를 참고하세요.

기타 고려사항

고려해야 할 몇 가지 중요한 사항이 있습니다.

소스 맵 및 축소된 코드:

소스 맵은 번들링 / 축소된 코드와 작성된 코드 간의 격차를 해소하기 위해 널리 채택된 도구입니다.

번들 앱에서 축소된 코드 문제를 해결하는 데 소스 맵이 사용되지 않나요?

소스 맵은 실제로 유용하지만 복잡하게 축소된 웹 앱을 프로파일링할 때 발생하는 문제를 완전히 해결하지는 않습니다. 소스 맵을 사용하면 DevTools에서 축소된 코드를 원래 소스 코드에 다시 매핑하여 디버깅을 더 쉽게 할 수 있습니다. 하지만 성능 분석에 소스 맵만 사용하는 경우 여전히 몇 가지 제한사항이 있을 수 있습니다. 예를 들어 프레임워크 내부와 작성된 코드가 시각적으로 분리되는 방식을 선택하는 것은 소스 맵만으로는 복잡합니다. 반면 확장성 API는 이러한 차이를 달성하고 개발자가 가장 편리하다고 생각하는 방식으로 표시할 수 있는 유연성을 제공합니다.

Chrome DevTools 확장 프로그램:

DevTools API를 사용하는 Chrome 확장 프로그램은 DevTools를 확장하는 데 널리 사용되는 도구입니다.

이 API가 제공되므로 전용 프로파일러 (예: Chrome DevTools 확장 프로그램)가 불필요하거나 권장되지 않나요?

아니요. 이 API는 Chrome DevTools 확장 프로그램과 같은 전용 프로파일러의 개발을 대체하거나 방해하기 위한 것이 아닙니다. 이러한 앱은 여전히 특정 요구사항에 맞게 조정된 전문 기능, 시각화, 워크플로를 제공할 수 있습니다. 성능 패널 확장성 API는 성능 패널의 브라우저 시각화와 맞춤 데이터의 원활한 통합을 만드는 것을 목표로 합니다.

앞으로 나아갈 길

확장성 API의 전망

더 많은 프레임워크 및 추상화 작업

다른 프레임워크와 추상화가 API를 채택하여 개발자의 프로파일링 환경을 개선할 수 있기를 기대합니다. 예를 들어 React는 프레임워크에 API를 실험적으로 채택했습니다. 이 계측은 클라이언트 및 서버 구성요소 렌더링과 React 일정 API 데이터를 표시합니다. React 페이지에서 자세한 내용과 사용 설정 방법을 알아보세요.

프로덕션 빌드

이 API의 목표 중 하나는 일반적으로 프레임워크 및 추상화 제공업체와 협력하여 프로덕션 빌드에서 계측을 채택하고 사용 설정하는 것입니다. 개발자가 사용자가 경험하는 대로 애플리케이션을 프로파일링할 수 있으므로 이러한 추상화로 개발된 앱의 성능에 큰 영향을 미칠 수 있습니다. console.timeStamp API는 속도가 빠르고 오버헤드가 낮으므로 이를 달성할 수 있다고 생각합니다. 하지만 현재 프레임워크는 API를 실험하고 있으며 어떤 종류의 계측이 더 확장 가능하고 개발자에게 유용한지 조사하고 있습니다.