Frontend

Angular Reborn: forget everything you think you know about the framework

If your last memory of Angular is Zone.js causing unpredictable re-renders and Webpack builds that take forever, you’re thinking of a framework that no longer exists. Modern Angular is something else entirely.

Equipe Blueprintblog6 min
Angular Reborn: forget everything you think you know about the framework

The dark ages we left behind

Anyone who worked with Angular during the golden years of SPAs knows the pain firsthand. It wasn’t just about performance—it was about predictability. You made a tiny change and couldn’t tell what would re-render. You saved the file and waited. And waited some more. The progress bar got stuck at 92% [chunk optimization] while your coffee went cold.

Three problems concentrated most of that suffering:

Zone.js and the cascade effect. Legacy Angular relied on a library called Zone.js to detect changes. It intercepted browser events—clicks, timers, HTTP requests—and forced the entire app to figure out what had changed. It was like throwing a stone into a pond: a small change triggered re-render ripples across the whole component tree. Slow. Heavy. Unpredictable.

Destructive SSR. Server-Side Rendering solved the initial-load problem but created a new one: it rendered HTML on the server, delivered it quickly to the browser—and then destroyed and rebuilt every DOM element on the client to add interactivity. The outcome was an "uncanny valley" of hydration: the screen appeared fast yet flickered, lost focus, and left users momentarily frozen.

Webpack and the endless builds. Every Ctrl+S could give you enough time to brew a fresh coffee. Webpack and the old CLI were simply too heavy for scalable applications. On large code bases, the dev server took minutes just to start.

The trinity of modern performance

Starting with Angular 17, the framework addressed these three issues architecturally. These weren’t quick patches—they were structural changes.

Quick indicators

Metrics and cues that summarize technical impact at a glance.

Angular Signals

Surgical reactivity—only what changed is updated

Non-destructive hydration

SSR that reuses the server’s DOM—no flash, no reload

Vite + esbuild

Build in <1 minute—HMR at the speed of thought

Signals: the end of global checks

The best analogy for Angular Signals is an Excel spreadsheet. When Cell A changes, only Cell B—whose formula depends on it—is updated. The rest of the sheet is left untouched.

That is exactly what Angular Signals do. Instead of Zone.js forcing Angular to check the whole component tree, each Signal knows exactly who depends on it. Updates are surgical—only what needs to change, changes.

typescript
import { signal, computed, effect } from '@angular/core';

@Component({
  template: `
    <p>Price: {{ finalPrice() }}</p>
    <button (click)="applyDiscount()">Apply 10%</button>
  `
})
export class ProductComponent {
  price = signal(100);
  discount = signal(0);

  // computed only recalculates when price or discount change
  finalPrice = computed(() =>
    this.price() * (1 - this.discount())
  );

  applyDiscount() {
    this.discount.set(0.1); // only finalPrice recalculates
  }
}

By Angular 20, all reactivity primitives built on Signals are stable: signal, computed, effect, linkedSignal, signal-based queries, and inputs. Migration from Zone.js to Signals can be done incrementally—the two coexist.

Non-destructive hydration: SSR that doesn’t flash

In Angular 17, the framework graduated from developer-preview hydration to stable-by-default non-destructive hydration in every new SSR app.

Legacy SSR tore down the server-generated DOM and rebuilt everything on the client. The new hydration reuses the existing DOM—the HTML received from the server is kept, and Angular simply "wakes up" interactivity on top of it, without any recreation.

The result is an ultra-fast First Contentful Paint that stays interactive. No flashes. No lost input focus. No awkward freeze between "visible" and "clickable."

Angular 19 pushed further with incremental hydration—using the @defer API, components hydrate on demand when the user actually wants to interact. Less JavaScript upfront, better perceived performance. Real-world tests by the Angular team showed 45% LCP improvements.

text
// app.config.ts — enable incremental hydration (Angular 19+)
import {
  provideClientHydration,
  withIncrementalHydration
} from '@angular/platform-browser';

export const appConfig = {
  providers: [
    provideClientHydration(
      withIncrementalHydration()
    )
  ]
};
tsx
<!-- The heavy component only hydrates when it enters viewport -->
@defer (on viewport) {
  <app-heavy-dashboard />
}
@placeholder {
  <div>Loading...</div>
}

Vite + esbuild: the end of Building... agony

Angular 17 removed Webpack from the critical path and adopted Vite + esbuild as the default build pipeline for every new project.

esbuild is written in Go and compiles hundreds of thousands of lines of code in under a minute. Vite handles the dev server with Hot Module Replacement that feels as fast as your thoughts.

The numbers are real: Angular reported up to 87% faster build times for hybrid-rendering projects. The dev server boots instantly. With Webpack out of the critical path, the Angular CLI is now 50% lighter in dependencies.

Legacy project? Migration is automated. Run ng update @angular/cli and the schematic does the heavy lifting: it migrates angular.json, removes legacy SSR builders, and merges the required tsconfig files.

The new control flow: templates that make sense

One of the most visible day-to-day changes is the new control-flow syntax, stable since Angular 18. Gone are *ngIf and *ngFor with their verbose structural syntax. Now it’s straightforward:

tsx
<!-- Before -->
<div *ngIf="user; else noUser">
  <span *ngFor="let item of items; trackBy: trackById">
    {{ item.name }}
  </span>
</div>
<ng-template #noUser>Login required</ng-template>

<!-- After -->
@if (user) {
  @for (item of items; track item.id) {
    <span>{{ item.name }}</span>
  }
} @else {
  Login required
}

More readable, better rendering performance, and the track in @for is now mandatory—enforcing best practices that were once optional and often forgotten.

What really changed in modern Angular

  • Angular Signals—surgical reactivity. No Zone.js, no global checks. Stable in Angular 20.
  • Non-destructive hydration—SSR that doesn’t flash. Server DOM is reused, not destroyed.
  • Incremental hydration—@defer hydrates on demand. 45% LCP gain in real apps.
  • Vite + esbuild—builds under 1 minute. Instant HMR. CLI 50% lighter.
  • New control flow—@if, @for, @switch natively. Stable in Angular 18.
  • Standalone components—NgModules optional. Default in all new projects.
  • The framework evolved. The question now is: did your code evolve too?

Article tags

Related articles

Get the latest articles delivered to your inbox.

Follow Us: