Angular Signals Performance Model यह समझाता है कि Signals internally कैसे work करते हैं, change detection को कैसे optimize करते हैं और क्यों Signals traditional Angular rendering model से ज्यादा efficient हैं। इस chapter का focus theory + practical understanding पर है, ताकि आप Signals को blindly नहीं बल्कि performance-aware तरीके से use करें।
Traditional Angular Change Detection Problem
Classic Angular में change detection:
- Zone.js के through trigger होती है
- Entire component tree check हो सकती है
- Unrelated components भी re-evaluate होते हैं
Large UI में इसका impact:
- Unnecessary re-renders
- Performance degradation
- Complex optimization (OnPush, manual checks)
Signals इसी problem को solve करने के लिए introduce किए गए।
Signals का Core Performance Idea
Signals का core idea है:
- Reactive dependency tracking
- Fine-grained updates
- Minimal recomputation
Angular यह track करता है कि:
- कौन सा signal
- किस template expression या computed signal में use हुआ
और change होने पर सिर्फ वही update होता है।
Push vs Pull Model
Traditional (Push-based)
- Event या async task push करता है change detection
- Angular guessing करता है क्या change हुआ
Signals (Pull-based)
- Template खुद signal value pull करता है
- Angular exact dependency graph बनाता है
Pull-based model ज्यादा accurate और efficient होता है।
Dependency Graph कैसे बनता है
जब template या computed signal में signal read होता है:
count();
Angular internally record करता है:
- count → dependent expression
यह graph runtime पर automatically maintain होता है।
Result:
- No manual wiring
- No decorators
- No subscriptions
Fine-Grained Rendering Explained
Example:
<p>{{ count() }}</p>
<p>{{ username() }}</p>
अगर count change होता है:
- Sirf पहला
<p>update होगा - दूसरा untouched रहेगा
Classic Angular में पूरा component check हो सकता था।
यह fine-grained rendering Signals की biggest performance win है।
Computed Signals Performance
Computed signals lazy होते हैं।
total = computed(() => this.price() * this.qty());
Behavior:
- Tab tak recompute नहीं होता जब तक कोई consumer read न करे
- Dependencies change होने पर cache invalidate होता है
- Multiple reads = single computation
यह memoization जैसा behavior provide करता है।
Effect Execution Model
Effects performance-wise carefully designed हैं।
effect(() => {
console.log(this.count());
});
Rules:
- Effect sirf dependency change पर run होता है
- Multiple changes batch हो सकते हैं
- Component destroy पर auto-cleanup होता है
इससे memory leaks और redundant execution avoid होती है।
Batching and Coalescing
Angular signal updates batch करता है।
count.set(1);
count.set(2);
count.set(3);
Result:
- Single recomputation
- Single render pass
यह batching UI smoothness improve करती है।
Signals और Change Detection Zones
Signals zone-less Angular की direction में design किए गए हैं।
Traditional Angular:
- Zone.js async events detect करता है
Signals:
- Explicit reactive dependencies
- Zone-less change propagation possible
Future Angular versions में Signals + zone-less mode default बनने की expectation है।
OnPush vs Signals Performance
OnPush:
- Manual optimization
- Requires discipline
- Easy to break
Signals:
- Default optimized
- Automatic
- Hard to misuse
Signals effectively OnPush का safer replacement बनते जा रहे हैं।
Signals in Large Component Trees
Large trees में Signals का behavior:
- Parent change ≠ child re-render
- Child change ≠ sibling re-render
- Only exact dependency update
यह deep component hierarchies में massive performance gain देता है।
Signal Granularity Best Practices
Performance maximize करने के लिए:
- Large object के बजाय small signals
- Feature-wise state split करें
- Computed signals granular रखें
Bad example:
state = signal({ user, products, settings });
Better:
user = signal<User | null>(null);
products = signal<Product[]>([]);
settings = signal<Settings>(defaultSettings);
Signals और Object Mutation Cost
Direct mutation performance issues create कर सकती है।
this.users().push(user); // no tracking
Correct:
this.users.update(list => [...list, user]);
Immutable updates Angular को exact change boundaries detect करने में help करते हैं।
Signals vs RxJS Performance Perspective
RxJS:
- Stream-based
- Operator overhead
- Subscription management
Signals:
- Direct dependency tracking
- No operators
- Minimal overhead
UI rendering के लिए Signals faster होते हैं, async streams के लिए RxJS efficient रहता है।
Memory Footprint
Signals:
- No subscriptions
- Automatic lifecycle management
- Lower memory footprint
RxJS misuse में memory leaks common हैं, Signals इस risk को eliminate करते हैं।
Signals with Lists and Loops
Large lists में Signals + trackBy combination powerful है।
<div *ngFor="let item of items(); trackBy: trackById">
Benefits:
- Minimal DOM updates
- Stable performance on large datasets
Common Performance Anti-Patterns
- One giant signal for entire app state
- Effects में heavy logic
- Frequent signal updates inside loops
- Signals से async orchestration
Signals fast हैं, लेकिन wrong usage cost create कर सकता है।
Measuring Signal Performance
Performance evaluate करने के तरीके:
- Angular DevTools
- Chrome Performance tab
- Manual profiling
Look for:
- Reduced change detection cycles
- Fewer DOM updates
- Stable frame rate
When Signals Shine the Most
Signals maximum benefit देते हैं:
- UI-heavy dashboards
- Real-time counters
- Form state rendering
- Complex component trees
When Signals Are Not the Bottleneck
Signals performance solve नहीं करते:
- Slow APIs
- Heavy backend logic
- Large DOM without virtualization
Correct bottleneck identify करना जरूरी है।
Summary of Performance Model
Angular Signals performance model based है:
- Fine-grained dependency tracking
- Lazy computation
- Batched updates
- Zone-less friendly rendering
Signals Angular rendering को guess-based से dependency-driven बनाते हैं। यह shift Angular applications को faster, predictable और future-ready बनाता है।
