Angular Signals changed everything.
No more heavy RxJS for simple state.
No more manual subscriptions everywhere.
Finer-grained reactivity.
Better performance.
But here’s the uncomfortable truth:
Signals made Angular faster — and also much easier to misuse.
Let’s talk about where developers are getting it wrong.
🚀 Why Signals Are Powerful
Signals give Angular:
- Fine-grained reactivity
- Automatic dependency tracking
- Cleaner state management
- Better compatibility with zoneless apps
Example:
count = signal(0);
increment() {
this.count.update(v => v + 1);
}
Template:
<p>{{ count() }}</p>
Simple. Reactive. Fast.
But speed + simplicity can create new problems.
❌ Misuse #1: Calling Signals Excessively in Templates
Bad pattern:
<p>{{ expensiveComputed() }}</p>
<p>{{ expensiveComputed() }}</p>
<p>{{ expensiveComputed() }}</p>
Each call re-evaluates dependencies.
If your computed logic is heavy, you just created hidden performance cost.
✔ Fix:
Store in a local template variable or simplify computed logic.
❌ Misuse #2: Overusing computed() for Heavy Logic
Bad pattern:
filteredUsers = computed(() => {
return this.users()
.filter(u => u.active)
.sort(...)
.map(...);
});
If users() changes often, this recalculates fully.
Signals are reactive — not magical.
✔ Fix:
- Break computations
- Normalize state
- Avoid expensive transformations inside computed
❌ Misuse #3: Using Effects Like Subscriptions
Developers are replacing RxJS subscriptions with effects everywhere.
Bad pattern:
effect(() => {
console.log(this.user());
});
Effects should be rare and intentional.
Too many effects:
- cause cascading updates
- create debugging nightmares
- feel like hidden side-effects
✔ Rule:
Use computed() for derivation.
Use effect() only for external side effects.
❌ Misuse #4: Treating Signals Like Global State
Putting everything in a service:
user = signal(null);
cart = signal([]);
theme = signal('light');
Now your app becomes tightly coupled and hard to test.
Signals are reactive primitives — not architecture.
❌ Misuse #5: Mixing Signals and RxJS Without Boundaries
Many apps now look like this:
- signals
- observables
- subjects
- effects
- async pipe
All together.
That’s not progress.
That’s confusion.
✔ Decide:
- UI state → signals
- Streams & async flows → RxJS
- Keep boundaries clear
🧠 The Real Shift Signals Introduced
Signals changed Angular’s mental model:
From:
"Change detection runs everywhere"
To:
"Reactivity happens where dependencies exist"
But this requires discipline.
Signals reward:
- clean state modeling
- small derivations
- clear boundaries
They punish:
- heavy computations
- hidden effects
- sloppy architecture
⚡ Are Signals Worth It?
Absolutely.
They:
- reduce unnecessary checks
- improve performance clarity
- simplify component state
- work beautifully with zoneless Angular
But performance doesn’t come from using signals.
It comes from using them correctly.
🔥 Final Thought
Signals didn’t just make Angular faster.
They made Angular more powerful.
And with more power comes the ability to:
- write elegant code
- or create subtle performance bugs
The choice is yours.
Top comments (0)