Alula ሐawandoHawandoH→ሐ

Tips to improve the performance of your angular app.

Don't just build it. Make it fast. Make it feel good.


📚 Table of Contents

  1. Introduction
  2. Use Lazy Loading for Feature Modules
  3. Use OnPush Change Detection
  4. Avoid Memory Leaks with Unsubscribing
  5. TrackBy with *ngFor
  6. Minimize Bundle Size
  7. Use Pure Pipes
  8. Avoid Complex Computation in Templates
  9. Optimize Third-Party Imports
  10. Leverage Angular CLI Production Flags
  11. Use Web Workers for Heavy Lifting
  12. Story Time: The App That Felt Laggy
  13. Further Reading

🧭 Introduction

Angular is powerful. But that power comes with responsibility.

A fast app isn't just about speed — it's about the feeling of speed. Users bounce when things lag. These tips will help you build apps that fly.


🧱 Use Lazy Loading for Feature Modules

We covered this in our lazy loading tutorial.

But here's the TL;DR:

{
  path: 'dashboard',
  loadChildren: () =>
    import('./dashboard/dashboard.module').then(m => m.DashboardModule)
}

Lazy loading cuts down the initial bundle size.


⚡ Use OnPush Change Detection

By default, Angular checks everything on every change.

That’s wasteful.

Use ChangeDetectionStrategy.OnPush for components that rely only on input props.

@Component({
  selector: 'app-card',
  templateUrl: './card.component.html',
  changeDetection: ChangeDetectionStrategy.OnPush
})
export class CardComponent { }

You’ll see a huge boost in large apps.


🧹 Avoid Memory Leaks with Unsubscribing

Subscriptions in Angular don't auto-clean themselves.

Use:

  • takeUntil() with Subject for manual cleanup
  • async pipe when you can
ngOnDestroy() {
  this.destroy$.next();
  this.destroy$.complete();
}

Memory leaks kill performance over time.


🔁 TrackBy with *ngFor

When looping over large lists, always use trackBy.

<li *ngFor="let item of items; trackBy: trackById">{{ item.name }}</li>
trackById(index: number, item: any): number {
  return item.id;
}

It prevents DOM re-creation and unnecessary re-rendering.


📦 Minimize Bundle Size

Use source-map-explorer:

npm run build -- --stats-json
npx source-map-explorer dist/main.*.js

You’ll see what’s bloating your bundle.

Then:

  • Remove unused dependencies
  • Switch to lighter alternatives
  • Split code with lazy modules

🧼 Use Pure Pipes

A pure pipe recalculates only when inputs change.

Avoid complex logic in templates. Put it in pipes.

@Pipe({
  name: 'capitalize',
  pure: true
})
export class CapitalizePipe implements PipeTransform {
  transform(value: string): string {
    return value.charAt(0).toUpperCase() + value.slice(1);
  }
}

⛔ Avoid Complex Computation in Templates

This is bad:

{{ calculateExpensiveValue(user) }}

It runs on every change detection cycle.

Move logic to the component or a memoized service.


📚 Optimize Third-Party Imports

Instead of:

import * as _ from 'lodash';

Use:

import debounce from 'lodash/debounce';

Tree shaking fails when you import everything.


🔧 Leverage Angular CLI Production Flags

Always build for production:

ng build --configuration production

It enables:

  • AOT compilation
  • Minification
  • Dead code elimination

You get a much smaller and faster app.


🧠 Use Web Workers for Heavy Lifting

If you're doing big calculations (image processing, sorting 10,000 items), use Web Workers.

ng generate web-worker heavy-task

Offload work from the main thread.


📖 Story Time: The App That Felt Laggy

Back when I was optimizing the first version of CoScrum, I noticed it felt sluggish.

Not broken. Just... heavy.

I opened Chrome DevTools, hit the Performance tab, and recorded a session.

Turns out, every component was using default change detection and recalculating even when nothing changed.

I switched some key components to OnPush, added trackBy, and pulled a charting library out of the main bundle.

It felt like I added a turbo engine.


📚 Further Reading

More tutorials to explore:


You don’t need to do everything above.

But pick 3–4 changes, test your app again. You’ll feel it.

// Until next time...
const performance = optimizeAngularApp();