Take an Angular app zoneless + signals
provideZonelessChangeDetection() and let signals drive reactivity instead.
Why ditch zone.js
setTimeout , promises, DOM events, and triggers a global detection cycle every time. On a large app, you re-check thousands of bindings when only three changed. Zoneless flips the logic: nothing re-renders until a signal read in the template has notified its change.
- ›
lighter bundle: you remove a ~100 kB dependency - ›
readable stack traces: no more zone.runframes everywhere - ›
targeted detection: only the components that depend on the changed signal get marked
Enabling zoneless
provideZoneChangeDetection and wire the zoneless provider:
Thinking in fine-grained reactivity
signal() , derived values with computed() , and side effects with effect() :
Gotchas to know
setTimeout(() => this.value = x) without going through a signal will no longer refresh the view. Same for RxJS subscriptions: you either use toSignal() or call signal.set() inside the subscribe . On the test side, switch Vitest to zoneless and replace fakeAsync / tick with await fixture.whenStable() . The official docs cover each case in the zoneless guide .
Zoneless doesn't magically make an app faster. It makes reactivity explicit : you know exactly why something re-renders, and that's what changes everything when debugging.