DEV Community

Cover image for Signals Made Angular Faster — But Also Easier to Misuse
Mridu Dixit
Mridu Dixit

Posted on

Signals Made Angular Faster — But Also Easier to Misuse

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);
}

Enter fullscreen mode Exit fullscreen mode

Template:

<p>{{ count() }}</p>

Enter fullscreen mode Exit fullscreen mode

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>

Enter fullscreen mode Exit fullscreen mode

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(...);
});

Enter fullscreen mode Exit fullscreen mode

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());
});

Enter fullscreen mode Exit fullscreen mode

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');

Enter fullscreen mode Exit fullscreen mode

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)