Skip to content

Instantly share code, notes, and snippets.

@schmkr
Last active July 24, 2020 10:26
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save schmkr/26c8169a1ff70a386700d9802fffd29a to your computer and use it in GitHub Desktop.
Save schmkr/26c8169a1ff70a386700d9802fffd29a to your computer and use it in GitHub Desktop.
Zoneless Angular App

Example of running an Angular app without NgZone

Angular app that is running without NgZone. Triggering change-detection happens like this:

merge(
	fromEvent(document, 'click'),
	fromEvent(document, 'mousemove'),
	fromEvent(document, 'keydown'),
	fromEvent(document, 'scroll'),
	fromEvent(document, 'touchstart'),
	fromEvent(document, 'touchend'),
	this.actions$,
	this.contentChangesSubject.asObservable()
).pipe(
	debounceTime(20)
).subscribe(_ => this.cdRef.detectChanges());

And in the main.ts file, the app is bootstrapped like this:

platformBrowserDynamic()
	.bootstrapModule(AppModule, {
		ngZone: 'noop' // <-- this line tells Angular to not use NgZone
	})
	.catch(err => console.error(err));	

And make sure to remove the import of zone.js from polyfills.ts and environment.ts.

<div (cdkObserveContent)="contentChanged()">
<router-outlet></router-outlet>
</div>
import { ChangeDetectionStrategy, ChangeDetectorRef, Component, OnDestroy } from '@angular/core';
import { Actions } from '@ngrx/effects';
import { Subject, Subscription, fromEvent, merge } from 'rxjs';
import { debounceTime } from 'rxjs/operators';
@Component({
selector: 'app-root',
changeDetection: ChangeDetectionStrategy.OnPush,
templateUrl: './app.component.html'
})
export class AppComponent implements OnDestroy {
private cdSubscription: Subscription;
private contentChangesSubject: Subject<void> = new Subject<void>();
constructor(
private readonly actions$: Actions,
private readonly cdRef: ChangeDetectorRef,
) {
this.cdSubscription = merge(
fromEvent(document, 'click'),
fromEvent(document, 'mousemove'),
fromEvent(document, 'keydown'),
fromEvent(document, 'scroll'),
fromEvent(document, 'touchstart'),
fromEvent(document, 'touchend'),
this.actions$,
this.contentChangesSubject.asObservable()
).pipe(
debounceTime(20)
).subscribe(_ => this.cdRef.detectChanges());
}
ngOnDestroy() {
this.cdSubscription.unsubscribe();
}
contentChanged() {
this.contentChangesSubject.next();
}
}
@schmkr
Copy link
Author

schmkr commented Jul 24, 2020

For me, debounceTime(20) was randomly chosen. Anyone has a good idea how to determine the right amount of time for debouncing?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment