Does OnPush still matter in Angular 21 with zoneless change detection

Angular 21 changed something subtle… but important. So the real question is: Does `OnPush`, as a change detection strategy, still matter now that zoneless is the default? Let’s rewind a bit. In legacy Angular (zone-based apps  — pre Angular 20): Angular used zone.js to trigger change detection on every async event. Meaning: - HTTP calls   - setTimeout   - user interactions  Everything triggered a full check. With Default strategy: Angular re-checks components even when nothing changed. In real apps, that meant: - Hundreds of components   - Deep component trees   - Unpredictable performance  This is where `OnPush` came in. It told Angular: “Only check this component when there’s a real reason.” That brought: ✔Better performance   ✔ Predictable rendering   ✔ Forced good architecture (immutability, clear data flow) That’s why `OnPush` became a production standard. --- Now enter Angular 21 (zoneless by default). The game changes. Angular no longer relies on zone.js. Change detection is no longer triggered globally. Instead: "It runs only when explicitly triggered (signals, inputs, events)" So the biggest cost is already gone: - No more global change detection   - No more automatic async-triggered checks  --- So… do we still need `OnPush`? Yes — but for different reasons. `OnPush` still gives you: ✔ Discipline — no silent mutations   ✔ Explicit boundaries — clearer update triggers   ✔ Protection — avoids unnecessary checks within the tree  --- Here’s the mental model: Zoneless → controls WHEN change detection runs   OnPush → controls WHAT gets checked  You still need both. So yes — `OnPush` still matters. Just not for the same reasons as before. Curious. In Angular 21, are you still using OnPush, or relying purely on zoneless + signals? #Angular #JavaScript #SoftwareEngineering #ChangeDetection

  • graphical user interface, application

For those asking what actually triggers change detection in a zoneless setup. These are the common explicit triggers: - Signal updates (computed / writable signals) - Input reference changes - DOM events (click, input, etc.) - Manual triggers (markForCheck, detectChanges) - Async pipe emissions (via RxJS subscriptions) This is why change detection becomes more predictable — it’s no longer global, it’s intentional. Did I miss anything you rely on in production?

To view or add a comment, sign in

Explore content categories