ngZoneEventCoalescing for Preventing Event Bubbling

1 분 소요

Root Cause

JavaScript incorporates event bubbling between parent and child elements. In many scenarios, this event bubbling leads to the handling of unnecessary events, causing performance issues. Similarly, Angular experiences event bubbling, negatively impacting rendering performance.

To address this, change detection is configured. However, in versions prior to Angular 9, even with change detection enabled, timing issues in ngAfterViewInit often necessitated encapsulating functions within setTimeout for proper execution.

ngAfterViewInit(){
    setTimeout(()=> {
        this.changeStatus()
    })
}

Angular 9 introduced a more fundamental solution to event bubbling. The setTimeout code block above can be replaced with cdr.detectChanges() to ensure events are applied correctly without timing conflicts.

ngAfterViewInit(){
    this.changeStatus();
    this.cdr.detectChanges();
}

Solution

In main.ts, add an option during Angular Module bootstrap configuration:

platformBrowserDynamic()
  .bootstrapModule(AppModule, { ngZoneEventCoalescing: true })

Additionally: Solution in Modern Angular (v17+)

Starting with Angular 17, the default architecture is based on Standalone APIs, which do not use NgModule.
In this environment, bootstrapApplication() in main.ts replaces platformBrowserDynamic().bootstrapModule(), and global application configuration is handled in the app.config.ts file.
The ngZoneEventCoalescing setting is a configuration option for NgZone. It is now configured using a provider function called provideZoneChangeDetection.

Solution (Standalone API-based - Angular 17+)

In your app.config.ts file, add provideZoneChangeDetection to the providers array and pass the option eventCoalescing: true.

// src/app/app.config.ts

import { ApplicationConfig, provideZoneChangeDetection } from '@angular/core';
import { provideRouter } from '@angular/router';

import { routes } from './app.routes';

export const appConfig: ApplicationConfig = {
  providers: [
    provideRouter(routes),

    // 1. Call the provider function for Zone.js configuration.
    // 2. Enable event coalescing via the options object.
    provideZoneChangeDetection({ eventCoalescing: true })
  ]
};

This appConfig is then passed to the bootstrapApplication function in main.ts, applying the configuration to the entire application.

// src/main.ts (for reference)

import { bootstrapApplication } from '@angular/platform-browser';
import { AppComponent } from './app/app.component';
import { appConfig } from './app/app.config';

bootstrapApplication(AppComponent, appConfig)
  .catch((err) => console.error(err));

References

댓글남기기