Performance Optimization
Angular includes many optimizations out of the box, but as applications grow, you may need to fine-tune both how quickly your app loads and how responsive it feels during use. This guide covers the tools and techniques Angular provides to help you build fast applications.Loading Performance
Loading performance determines how quickly your application becomes visible and interactive. Slow loading directly impacts Core Web Vitals like Largest Contentful Paint (LCP) and Time to First Byte (TTFB).Lazy Loading Routes
Lazy loading defers loading route components until navigation, reducing the initial bundle size:When to use: Applications with multiple routes where not all are needed on initial load. This is one of the most effective ways to reduce initial bundle size.
Deferred Loading with @defer
The@defer block splits components into separate bundles that load on demand:
- Viewport Trigger
- Interaction Trigger
- Idle Trigger
- Timer Trigger
When to use: Components not visible on initial render, heavy third-party libraries, below-the-fold content.
Prefetching Deferred Content
You can prefetch deferred content before it’s needed:Immediate Prefetch
Idle Prefetch
Hover Prefetch
Timer Prefetch
Runtime Performance
Runtime performance determines how responsive your application feels after it loads. Angular’s change detection system keeps the DOM in sync with your data, and optimizing how and when it runs is the primary lever for improving runtime performance.OnPush Change Detection
OnPush change detection instructs Angular to run change detection for a component subtree only when:- The root component of the subtree receives new inputs (compared with
==) - Angular handles an event in the subtree’s root component or any of its children
Understanding OnPush Scenarios
- Event in Default Component
- Event in OnPush Component
- New Inputs to OnPush
If Angular handles an event within a component without OnPush, the framework executes change detection on the entire component tree, skipping OnPush subtrees that haven’t received new inputs.
Using trackBy for Performance
When rendering lists, usetrack to help Angular identify which items have changed:
Why use trackBy? Without proper tracking, Angular recreates DOM elements when the array reference changes, even if the items are the same. This causes expensive DOM operations and loses component state.
Optimizing Computed Values
Use computed signals for expensive calculations to avoid recalculating on every change detection:Zoneless Change Detection
Zoneless change detection removes ZoneJS overhead and triggers change detection only when signals or events indicate a change:app.config.ts
When to use: New applications (default in Angular v21+), or existing applications ready to migrate. Zoneless mode requires using signals for reactive state management.
Measuring Performance
Chrome DevTools Profiling
Analyze Angular Track
Look for the “Angular” track in the flame chart to see:
- Component rendering times
- Change detection cycles
- Lifecycle hook execution
Angular DevTools
The Angular DevTools browser extension provides:Component Inspector
Inspect component tree, view properties, and modify state in real-time
Profiler
Visualize change detection cycles and identify performance bottlenecks
Performance Checklist
Loading Performance
Loading Performance
- Implement lazy loading for routes not needed on initial load
- Use
@deferblocks for heavy components below the fold - Optimize images with NgOptimizedImage directive
- Consider server-side rendering for content-heavy pages
- Enable production mode for deployments
Runtime Performance
Runtime Performance
- Use OnPush change detection for presentational components
- Always use
trackwith unique identifiers in@forloops - Use computed signals for derived values
- Avoid complex logic in templates
- Consider zoneless change detection for new applications
Code Organization
Code Organization
- Keep components focused on presentation
- Move business logic to services
- Use pure pipes for transformations
- Avoid subscriptions in components (use async pipe or signals)
- Unsubscribe from observables to prevent memory leaks
Bundle Size
Bundle Size
- Analyze bundle size with
ng build --stats-json - Remove unused dependencies
- Use tree-shakable providers
- Lazy load feature modules
- Use dynamic imports for large libraries
What to Optimize First
Profile your application first using Chrome DevTools to identify specific bottlenecks. As a general starting point:Slow Initial Load
- Use
@deferto split large components - Implement lazy loading for routes
- Enable server-side rendering
- Optimize images with NgOptimizedImage
Slow Interactions
- Enable zoneless change detection
- Look for slow computations in templates
- Use OnPush change detection strategy
- Add trackBy functions to lists
Pro Tip: Don’t optimize prematurely. Profile first, identify actual bottlenecks, then optimize those specific areas.
Next Steps
Learn about security best practices in Angular applications
