Angular Performance Optimization
Master Angular Performance Optimization with OnPush Change Detection, Signals, Lazy Loading, Deferrable Views, trackBy, Virtual Scrolling, SSR, Hydration, RxJS optimization, architecture diagrams, enterprise best practices, and interview questions.
Performance optimization is one of the most important aspects of enterprise Angular development.
A fast application provides:
- Better user experience
- Faster page loads
- Lower memory usage
- Reduced CPU utilization
- Better SEO
- Improved scalability
Modern Angular (v17+) introduces several powerful performance features including:
- Signals
- OnPush Change Detection
- Deferrable Views
- Hydration
- Standalone Components
- Optimized Rendering
This guide covers the most important Angular performance optimization techniques used in production applications.
Table of Contents
- Why Performance Matters
- Performance Architecture
- Lazy Loading
- Standalone Components
- OnPush Change Detection
- Signals
- Computed Signals
- trackBy
- Virtual Scrolling
- Deferrable Views
- Image Optimization
- SSR & Hydration
- RxJS Optimization
- Bundle Optimization
- Enterprise Banking Example
- Performance Checklist
- Top 10 Interview Questions
- Summary
Why Performance Matters
Performance directly affects:
- User satisfaction
- SEO rankings
- Mobile experience
- Server costs
- Conversion rates
A high-performance Angular application should:
- Load quickly
- Render efficiently
- Minimize network requests
- Update only affected UI
- Use memory efficiently
Performance Architecture
flowchart TD
User
User --> LazyLoading
LazyLoading --> Signals
Signals --> OnPush
OnPush --> ComputedSignals
ComputedSignals --> OptimizedRendering
OptimizedRendering --> DOM
1. Lazy Loading
Load feature modules only when needed.
Instead of downloading the entire application initially,
Angular loads feature code only when users navigate to it.
export const routes: Routes = [
{
path:'admin',
loadComponent: () =>
import('./admin/admin.component')
.then(m => m.AdminComponent)
}
];
Benefits
- Smaller initial bundle
- Faster startup
- Better scalability
Lazy Loading Architecture
flowchart LR
Browser
Browser --> HomeBundle
Browser --> AdminRoute
AdminRoute --> AdminBundle
2. Standalone Components
Modern Angular recommends Standalone Components.
@Component({
standalone:true,
selector:'app-home',
templateUrl:'./home.html'
})
export class HomeComponent{}
Benefits
- Smaller bundles
- Simpler architecture
- Better tree shaking
- Faster compilation
3. OnPush Change Detection
Use OnPush for feature components.
@Component({
changeDetection:
ChangeDetectionStrategy.OnPush
})
Benefits
- Fewer Change Detection cycles
- Lower CPU usage
- Better rendering performance
Default vs OnPush
| Feature | Default | OnPush |
|---|---|---|
| Checks Every Cycle | ✅ Yes | ❌ No |
| Enterprise Ready | ⚠️ | ✅ |
| Performance | Good | Excellent |
4. Use Signals for UI State
Signals provide fine-grained rendering.
counter = signal(0);
increment(){
this.counter.update(
value => value + 1
);
}
Only dependent views update.
Signals Rendering
flowchart LR
Signal
Signal --> Component
Component --> UpdatedDOM
5. Use Computed Signals
Avoid duplicated calculations.
❌ Wrong
total = signal(0);
updateTotal(){
this.total.set(
this.price()
+
this.tax()
);
}
✅ Correct
total = computed(() =>
this.price()
+
this.tax()
);
Benefits
- Automatic recalculation
- Memoization
- Less code
6. Use trackBy with Lists
Without trackBy, Angular may recreate every DOM element.
❌
<li *ngFor="let user of users">
{{user.name}}
</li>
✅
<li
*ngFor="let user of users;
trackBy:trackById">
{{user.name}}
</li>
trackById(
index:number,
user:User
){
return user.id;
}
Benefits
- Fewer DOM updates
- Better scrolling
- Faster rendering
trackBy Architecture
flowchart LR
OldList
OldList --> TrackBy
TrackBy --> ReusedDOM
ReusedDOM --> UpdatedList
7. Virtual Scrolling
Render only visible items.
Instead of rendering 100,000 rows,
Angular renders only visible rows.
<cdk-virtual-scroll-viewport
itemSize="60">
<div
*cdkVirtualFor="let user of users">
{{user.name}}
</div>
</cdk-virtual-scroll-viewport>
Benefits
- Lower memory usage
- Smooth scrolling
- Faster rendering
Virtual Scrolling
flowchart TD
LargeDataset
LargeDataset --> VisibleItems
VisibleItems --> DOM
8. Deferrable Views
Modern Angular supports deferred loading.
@defer {
<app-recommendations/>
}
@placeholder {
Loading...
}
Benefits
- Faster first paint
- Smaller initial rendering cost
- Improved Core Web Vitals
Deferrable View Flow
flowchart LR
PageLoad
PageLoad --> MainContent
MainContent --> DeferredContent
9. Image Optimization
Best practices
- Use modern formats (WebP, AVIF)
- Compress large images
- Lazy-load offscreen images
- Specify width and height
- Serve responsive images
<img
src="hero.webp"
loading="lazy"
width="600"
height="400"
alt="Dashboard">
Benefits
- Faster loading
- Reduced bandwidth
- Better Largest Contentful Paint (LCP)
10. SSR and Hydration
Server-Side Rendering generates HTML on the server.
Hydration attaches Angular behavior without recreating the DOM.
flowchart LR
Server
Server --> HTML
HTML --> Browser
Browser --> Hydration
Hydration --> InteractiveUI
Benefits
- Better SEO
- Faster First Contentful Paint (FCP)
- Better Largest Contentful Paint (LCP)
11. Optimize RxJS
Avoid unnecessary subscriptions.
Use the Async Pipe.
<div>
{{ users$ | async | json }}
</div>
Use operators wisely.
search$
.pipe(
debounceTime(300),
distinctUntilChanged(),
switchMap(
term =>
this.search(term)
)
);
Benefits
- Reduced API calls
- Better responsiveness
- Automatic subscription cleanup
12. Bundle Optimization
Recommendations
- Remove unused libraries
- Use tree shaking
- Lazy-load large features
- Avoid duplicate dependencies
- Enable production builds
ng build --configuration production
Benefits
- Smaller JavaScript bundles
- Faster downloads
- Improved startup time
Enterprise Banking Example
Banking Dashboard
Optimization Techniques
- Standalone Components
- Lazy Loading
- Signals
- Computed Signals
- OnPush
- Virtual Scrolling
- SSR
- Hydration
- Deferrable Views
- RxJS Optimization
Architecture
flowchart TD
Browser
Browser --> SSR
SSR --> Hydration
Hydration --> Signals
Signals --> OnPush
OnPush --> Dashboard
Dashboard --> VirtualScroll
Dashboard --> DeferredWidgets
Dashboard --> OptimizedUI
Benefits
- Faster startup
- Lower memory usage
- Reduced CPU utilization
- Excellent scalability
- Better user experience
Performance Optimization Checklist
| Optimization | Benefit |
|---|---|
| Lazy Loading | Smaller initial bundle |
| Standalone Components | Better tree shaking |
| OnPush | Fewer checks |
| Signals | Fine-grained rendering |
| Computed Signals | Memoization |
| trackBy | Less DOM recreation |
| Virtual Scrolling | Lower memory usage |
| Deferrable Views | Faster initial render |
| SSR | Better SEO |
| Hydration | Faster interactivity |
| Async Pipe | Automatic subscriptions |
| Production Build | Smaller bundle |
Common Performance Mistakes
Mutating Objects
❌ Wrong
this.user.name = 'John';
✅ Correct
this.user = {
...this.user,
name:'John'
};
Missing trackBy
Large lists without trackBy cause unnecessary DOM recreation.
Manual Subscriptions Everywhere
Prefer the Async Pipe whenever rendering Observable data.
Heavy Template Methods
❌
{{ calculateTotal() }}
✅
total = computed(() =>
this.calculateTotal()
);
Loading Everything Initially
Lazy-load large features and defer non-critical UI.
Performance Best Practices
- Use Standalone Components.
- Lazy-load feature areas.
- Prefer OnPush for feature components.
- Use Signals for local UI state.
- Use Computed Signals for derived values.
- Use immutable updates.
- Add
trackByto large lists. - Use Virtual Scrolling for large datasets.
- Defer non-critical UI.
- Build using production configuration.
- Measure performance before optimizing.
- Continuously monitor Core Web Vitals.
Advantages
| Technique | Benefit |
|---|---|
| Signals | Fine-grained updates |
| OnPush | Reduced Change Detection |
| Lazy Loading | Faster startup |
| Virtual Scrolling | Lower memory usage |
| SSR | Better SEO |
| Hydration | Faster interaction |
| Deferrable Views | Improved Core Web Vitals |
| Async Pipe | Cleaner RxJS usage |
Top 10 Angular Performance Optimization Interview Questions
1. What are the most important Angular performance optimization techniques?
Answer
Use Lazy Loading, Standalone Components, OnPush Change Detection, Signals, Computed Signals, Virtual Scrolling, trackBy, Deferrable Views, SSR, Hydration, and RxJS best practices.
2. Why is OnPush faster?
Answer
OnPush reduces unnecessary Change Detection by checking components only when specific triggers occur, such as input reference changes, template events, Signal updates, Async Pipe emissions, or manual marking.
3. How do Signals improve performance?
Answer
Signals provide fine-grained dependency tracking so Angular updates only the parts of the UI that depend on the changed Signal.
4. Why should trackBy be used?
Answer
trackBy allows Angular to reuse existing DOM elements instead of recreating them, improving rendering performance for large lists.
5. What is Virtual Scrolling?
Answer
Virtual Scrolling renders only the visible items in a large list, reducing memory usage and improving scrolling performance.
6. What are Deferrable Views?
Answer
Deferrable Views (@defer) delay rendering of non-critical content until it is needed, reducing the initial rendering cost.
7. Why are Standalone Components recommended?
Answer
They simplify application structure, improve tree shaking, reduce bundle size, and work well with modern Angular features.
8. What is the role of SSR and Hydration?
Answer
SSR improves SEO and initial page load by rendering HTML on the server. Hydration makes the server-rendered HTML interactive without recreating the DOM.
9. What are RxJS performance best practices?
Answer
Use the Async Pipe, debounce user input, cancel stale requests with switchMap, avoid nested subscriptions, and unsubscribe appropriately when not using the Async Pipe.
10. What performance architecture is recommended for enterprise Angular applications?
Answer
Use Standalone Components, Lazy Loading, OnPush Change Detection, Signals for UI state, Computed Signals for derived values, RxJS for asynchronous operations, Virtual Scrolling for large datasets, Deferrable Views for non-critical content, and SSR with Hydration for optimal rendering.
Interview Cheat Sheet
| Requirement | Recommended Solution |
|---|---|
| Local UI State | Signals |
| Derived State | computed() |
| Async Operations | RxJS |
| Large Lists | trackBy + Virtual Scrolling |
| Change Detection | OnPush |
| Lazy Features | Lazy Loading |
| Initial Render | @defer |
| SEO | SSR |
| Faster Interactivity | Hydration |
| Production Deployment | Production Build |
Summary
Angular performance optimization is achieved by combining multiple techniques rather than relying on a single feature. Standalone Components, Lazy Loading, OnPush Change Detection, Signals, Computed Signals, Virtual Scrolling, Deferrable Views, SSR, Hydration, and RxJS optimization together create applications that load quickly, render efficiently, and scale well. Measuring performance with real metrics and applying optimizations where they provide value is the key to building enterprise-grade Angular applications.
Key Takeaways
- ✔ Prefer Standalone Components for new Angular applications.
- ✔ Lazy-load feature areas to reduce initial bundle size.
- ✔ Use OnPush for reusable feature components.
- ✔ Use Signals for local reactive UI state.
- ✔ Use Computed Signals for derived values.
- ✔ Add
trackByfor large lists. - ✔ Use Virtual Scrolling for large datasets.
- ✔ Defer non-critical UI with
@defer. - ✔ Combine SSR and Hydration for better SEO and startup performance.
- ✔ Profile your application and optimize based on measured bottlenecks.
Next Article
➡️ 93-Lazy-Loading-QA.md