Clement Yuen
← Back to articles
Angular·Intermediate

Angular Performance: Practical Techniques for Faster Applications

14 Aug 2026 · 9 min read · Intermediate

  • #Angular
  • #Performance
  • #ChangeDetection

Share

Angular performance work pays off when you measure first, then change the few paths that dominate render cost.

Measure before optimizing

Start with Chrome Performance and Lighthouse, then Angular-specific signals:

  • Unnecessary change detection cycles
  • Large component trees re-rendering on unrelated updates
  • Heavy modules loaded on first paint

If you cannot name the bottleneck, do not start with zoneless experiments.

OnPush as a default

ChangeDetectionStrategy.OnPush is still one of the highest leverage defaults:

Typescript
import { ChangeDetectionStrategy, Component, input } from '@angular/core';

@Component({
  selector: 'app-user-chip',
  changeDetection: ChangeDetectionStrategy.OnPush,
  template: `<span>{{ name() }}</span>`,
})
export class UserChipComponent {
  readonly name = input.required<string>();
}

Combine OnPush with immutable inputs or Signals so Angular can skip subtrees confidently.

Modern control flow and @defer

Defer non-critical UI so the first viewport stays light:

Html
@defer (on viewport) {
  <app-analytics-panel />
} @placeholder {
  <div class="skeleton h-40"></div>
}

Use on idle, on interaction, or on viewport based on whether the block is below the fold or triggered by user action.

TrackBy and list rendering

Large lists without identity tracking force DOM churn:

Html
@for (row of rows(); track row.id) {
  <tr>
    <td>{{ row.label }}</td>
  </tr>
}

Prefer stable ids over index tracking whenever the collection reorders.

Bundle and dependency hygiene

  • Prefer standalone imports over barrel files that pull half the library.
  • Lazy-load routed features with loadComponent / loadChildren.
  • Audit PrimeNG (or any UI kit) imports—import the directive/component you need, not a mega module.

Change detection conscious templates

Avoid:

  • Heavy method calls in templates ({{ computeScore() }})
  • Deep pipes that allocate on every cycle
  • Subscribing in templates without async / toSignal

Prefer:

Typescript
readonly score = computed(() => this.computeScore(this.model()));

Conclusion

Fast Angular apps are usually the result of OnPush + lean templates + deferred secondary UI + honest measurement—not a single framework flag.

Related Articles