|
| 1 | +--- |
| 2 | +title: Track Angular Components |
| 3 | +description: "Learn how Sentry's Angular SDK allows you to monitor the rendering performance of your application and its components." |
| 4 | +--- |
| 5 | + |
| 6 | +Sentry's Angular SDK offers a feature to monitor the performance of your Angular components: component tracking. Enabling this feature provides you with spans in your transactions that show the initialization and update cycles of your Angular components. This allows you to get a drilled-down view into how your components are behaving so you can do things like identify slow initializations or frequent updates, which might have an impact on your app's performance. |
| 7 | + |
| 8 | +<Alert> |
| 9 | + |
| 10 | +To set up component tracking, you need to configure performance monitoring. For details on how to do this, check out our [Performance documentation](/platforms/javascript/guides/angular/performance/). |
| 11 | + |
| 12 | +</Alert> |
| 13 | + |
| 14 | +To track your components as part of your transactions, use any (or a combination) of the following options. |
| 15 | + |
| 16 | +## Using `TraceDirective` |
| 17 | + |
| 18 | +`TraceDirective` tracks a duration between the `OnInit` and `AfterViewInit` lifecycle hooks in your component template. It adds spans called **`ui.angular.init`** to the currently active transaction that allows you to track specific individual instances of your components. If you want to track all instances instead, use [`TraceClassDecorator`](#using-traceclassdecorator). |
| 19 | + |
| 20 | +Import `TraceModule` either globally in your application's `app.module.ts` file or in the module(s) in which |
| 21 | +you want to track your components: |
| 22 | + |
| 23 | +```typescript {filename:app.module.ts} |
| 24 | +import * as Sentry from "@sentry/angular"; |
| 25 | + |
| 26 | +@NgModule({ |
| 27 | + // ... |
| 28 | + imports: [Sentry.TraceModule], |
| 29 | + // ... |
| 30 | +}) |
| 31 | +export class AppModule {} |
| 32 | +``` |
| 33 | + |
| 34 | +Then, in your component's template, add the directive to all components you want to track. Remember to give the `trace` attribute a name, which will be shown in the span's description: |
| 35 | + |
| 36 | +```html {filename:app.component.ts} |
| 37 | +<app-header [trace]="'header'"></app-header> |
| 38 | +<articles-list [trace]="'articles-list'"></articles-list> |
| 39 | +<app-footer [trace]="'footer'"></app-footer> |
| 40 | +``` |
| 41 | + |
| 42 | +<Alert level="info" title="Compatibility"> |
| 43 | + |
| 44 | +If you're using version 6 of the Angular SDK, using `TraceDirective` or `TraceModule` causes a |
| 45 | +compiler error at application compile time of your Angular application. This is a [known issue](https://github.com/getsentry/sentry-javascript/issues/3282) |
| 46 | +of our Angular SDK v6 and it was [fixed](https://github.com/getsentry/sentry-javascript/issues/4644) |
| 47 | +in version 7. We recommend upgrading to the latest Angular SDK version. |
| 48 | +Otherwise, please use the other options (`TraceClassDecorator` and `TraceMethodDecorator`) |
| 49 | +below to track your Angular components. |
| 50 | + |
| 51 | +</Alert> |
| 52 | + |
| 53 | +## Using `TraceClassDecorator` |
| 54 | + |
| 55 | +`TraceClassDecorator` tracks the duration between the `OnInit` and `AfterViewInit` lifecycle hooks in components. It adds spans called **`ui.angular.init`** to the currently active transaction. In contrast to [`TraceDirective`](#using-tracedirective), `TraceClassDecorator` tracks all instances of the component(s) you add it to, creating spans for each component instance. |
| 56 | + |
| 57 | +Just add `TraceClassDecorator` to the components you want to track: |
| 58 | + |
| 59 | +```typescript {filename:header.component.ts} |
| 60 | +import { Component } from "@angular/core"; |
| 61 | +import * as Sentry from "@sentry/angular"; |
| 62 | + |
| 63 | +@Component({ |
| 64 | + selector: "app-header", |
| 65 | + templateUrl: "./header.component.html", |
| 66 | +}) |
| 67 | +@Sentry.TraceClassDecorator() |
| 68 | +export class HeaderComponent { |
| 69 | + // ... |
| 70 | +} |
| 71 | +``` |
| 72 | + |
| 73 | +## Using `TraceMethodDecorator` |
| 74 | + |
| 75 | +`TraceMethodDecorator` tracks specific component lifecycle hooks as point-in-time spans. The added spans are called **`ui.angular.[methodname]`** (like, `ui.angular.ngOnChanges`). For example, you can use this decorator to track how often component changes are detected during an ongoing transaction: |
| 76 | + |
| 77 | +```typescript {filename:login.component.ts} |
| 78 | +import { Component, OnInit } from "@angular/core"; |
| 79 | +import * as Sentry from "@sentry/angular"; |
| 80 | + |
| 81 | +@Component({ |
| 82 | + selector: "app-login", |
| 83 | + templateUrl: "./login.component.html", |
| 84 | +}) |
| 85 | +export class LoginComponent implements OnChanges { |
| 86 | + @Sentry.TraceMethodDecorator() |
| 87 | + ngOnChanges(changes: SimpleChanges) {} |
| 88 | +} |
| 89 | +``` |
| 90 | + |
| 91 | +## Advanced Usage |
| 92 | + |
| 93 | +You can combine our tracking utilities and track the bootstrapping duration of your app. |
| 94 | + |
| 95 | +### Combining Component Tracking Utilities |
| 96 | + |
| 97 | +To get the best insights into your components' performance, you can combine `TraceDirective`, `TraceClassDecorator`, and `TraceMethodDecorator`. This allows you to track component initialization durations as well as arbitrary lifecycle events, such as change and destroy events: |
| 98 | + |
| 99 | +```typescript {filename:user-card.component.ts} |
| 100 | +import { Component, OnInit } from "@angular/core"; |
| 101 | +import * as Sentry from "@sentry/angular"; |
| 102 | + |
| 103 | +@Component({ |
| 104 | + selector: "app-user-card", |
| 105 | + templateUrl: "./user-card.component.html", |
| 106 | +}) |
| 107 | +@Sentry.TraceClassDecorator() |
| 108 | +export class UserCardComponent implements OnChanges, OnDestroy { |
| 109 | + @Sentry.TraceMethodDecorator() |
| 110 | + ngOnChanges(changes: SimpleChanges) {} |
| 111 | + |
| 112 | + @Sentry.TraceMethodDecorator() |
| 113 | + ngOnDestroy() {} |
| 114 | +} |
| 115 | +``` |
| 116 | + |
| 117 | +User `TraceDirective` if you only want to track components in certain instances or locations: |
| 118 | + |
| 119 | +```html {user-card.component.html} |
| 120 | +<div> |
| 121 | + <app-icon trace="user-icon">user</app-icon> |
| 122 | + <label>{{ user.name }}</label> |
| 123 | + <!--...--> |
| 124 | + <app-button trace="save-user">Save</app-button> |
| 125 | +</div> |
| 126 | +``` |
| 127 | + |
| 128 | +### Track Angular Bootstrapping |
| 129 | + |
| 130 | +You can add your own custom spans by attaching them to the currently active transaction using the `getActiveTransaction` |
| 131 | +helper. For example, you can track the duration of the Angular bootstrapping process to find out how long your app takes to bootstrap on your users' devices: |
| 132 | + |
| 133 | +```javascript |
| 134 | +import { enableProdMode } from "@angular/core"; |
| 135 | +import { platformBrowserDynamic } from "@angular/platform-browser-dynamic"; |
| 136 | +import * as Sentry from "@sentry/angular"; |
| 137 | + |
| 138 | +import { AppModule } from "./app/app.module"; |
| 139 | + |
| 140 | +// ... |
| 141 | + |
| 142 | +const activeTransaction = Sentry.getActiveTransaction(); |
| 143 | +const bootstrapSpan = |
| 144 | + activeTransaction && |
| 145 | + activeTransaction.startChild({ |
| 146 | + description: "platform-browser-dynamic", |
| 147 | + op: "ui.angular.bootstrap", |
| 148 | + }); |
| 149 | + |
| 150 | +platformBrowserDynamic() |
| 151 | + .bootstrapModule(AppModule) |
| 152 | + .then(() => console.log(`Bootstrap success`)) |
| 153 | + .catch(err => console.error(err)) |
| 154 | + .finally(() => { |
| 155 | + if (bootstrapSpan) { |
| 156 | + bootstrapSpan.finish(); |
| 157 | + } |
| 158 | + }); |
| 159 | +``` |
| 160 | + |
| 161 | +Learn more about [custom instrumentation](../../performance/instrumentation/custom-instrumentation/). |
0 commit comments