Angular

    Optimising Angular Applications with Zone-Less Change Detection


    Introduction

    Angular's default mechanism of change detection is run by Zone.js, which patches the browser APIs to track the asynchronous operation and then triggers change detection when needed. Such an approach simplifies reactivity but creates performance overhead in highly loaded applications with frequent asynchronous events. The zone-less approach avoids many unnecessary change detection cycles, which can significantly optimize performance.

    Why Consider Zone-Less Change Detection?

    1. Reduced Change Detection Overhead

    Zone.js performs change detection on every asynchronous operation (setTimeout, HTTP requests, events on the DOM), though unnecessary. This increases performance overheads.

    2. Greater Control Over Component Updates

    Manual control over change detection provides greater control over UI updates, responding and improving overall responsiveness, while the updates are already minimized.

    3. Better Performance on High-Frequency Updates

    Applications working with real-time data, heavy DOM manipulations or high-frequency events like WebSockets, could make use of fewer unnecessary cycles of change detection.

    How to Remove Zone.js in Angular

    Step 1: Disable Zone.js

    To start, remove Zone.js from your application by modifying polyfills.ts:

    // Remove or comment out the following line in polyfills.ts// import 'zone.js';  // Included with Angular CLI.Also, disable automatic change detection in main.ts:import { bootstrapApplication } from '@angular/platform-browser';import { AppComponent } from './app/app.component';import { provideZoneChangeDetection } from '@angular/core';bootstrapApplication(AppComponent, {  providers: [provideZoneChangeDetection(false)],});

    This ensures that Angular no longer depends on Zone.js for tracking asynchronous tasks.

    Manually controlling change detection

    Since Zone.js no longer governs change detection, we'll be responsible for triggering updates with Angular's ChangeDetectorRef when needed.

    1. Manual Change Detection Using ChangeDetectorRef

    import { Component, ChangeDetectorRef } from '@angular/core';@Component({  selector: 'app-manual-detection',  template: `<p>Counter: {{ counter }}</p>             <button (click)="increment()">Increment</button>`})export class ManualDetectionComponent {  counter = 0;  constructor(private cdr: ChangeDetectorRef) {}  increment() {    this.counter++;    this.cdr.detectChanges(); // Manually trigger change detection  }}

     

    2. Applying OnPush Change Detection Strategy

    Components using ChangeDetectionStrategy.OnPush only re-renders when input properties change or when manually triggered:

    import { ChangeDetectionStrategy, Component } from '@angular/core';@Component({  selector: 'app-optimized',  template: `<p>Optimized Counter: {{ counter }}</p>             <button (click)="increment()">Increment</button>`,  changeDetection: ChangeDetectionStrategy.OnPush})export class OptimizedComponent {  counter = 0;  increment() {    this.counter++;  }}

    OnPush avoids unnecessary change detection, thus updates only when the component's inputs change.

    Handling Asynchronous Operations

    Without Zone.js, Angular won't automatically detect changes from async operations, like HTTP requests or setTimeout. You'll have to call detectChanges() or markForCheck() yourself.

    Example: Update UI After an HTTP Request

    import { Component, ChangeDetectorRef } from '@angular/core';import { HttpClient } from '@angular/common/http';@Component({ selector: 'app-data-fetch', template: `<p>Data: {{ data }}</p>`})export class DataFetchComponent { data: any; constructor(private http: HttpClient, private cdr: ChangeDetectorRef) { this.fetchData(); } fetchData() { this.http.get('https://api.example.com/data').subscribe(response => { this.data = response; this.cdr.detectChanges(); // Manually trigger change detection }); }}

    Zone-less change detection with Best Practices

    1. ChangeDetectionStrategy.OnPush should be used by each component so that the number of unnecessary checks on the changed variables is decreased.
    2. Signals or RxJS. Observables with RxJS and signals with Angular will be much better at dealing with state change issues.
    3. Using ChangeDetectorRef. detectChanges() or markForCheck() for manually initiating a change.ry.
    4. Batching updates for UI components should be considered to minimize the overhead of performance issues.
    5. Manual initiation of change detections as little as possible to minimize overhead.

     

    Why Use Optimistic UI?

    Zone-less strategy in Angular would improve performance through the reduction of unnecessary change detection cycles. Even though it will require more control over the components' updates in a manual approach, it serves as a well-tuned alternative for high performance, especially with applications that do real-time updates or frequent ones. Developers would be able to optimize their application for better efficiency and responsiveness based on best practices and Angular built-in mechanisms.

     Ready to transform your business with our technology solutions? Contact Us today to Leverage Our Angular Expertise.

    Contact Us

    Comment

    Share

    facebook
    LinkedIn
    Twitter
    Mail
    Angular

    Related Center Of Excellence