Reputation: 73731
While debugging in Chrome to find the source of some slow response in my application, I noticed in the Peformance tab that holding down the Shift key generates repeating keydown
events, each one triggering change detection in Angular. The image below shows the Performance tab for one of them. These events are not useful for my application; I know that nothing changes when Shift and Ctrl are pressed by themselves. I only want to know if the key is down when a click event occurs, or when a character or function key is pressed. The extra activity reported in the Performance tab also makes it more difficult to analyze what is of actual interest for my debugging.
Is there a way to prevent or to cancel change detection on global keydown
events for keys like Shift and Ctrl?
Upvotes: 6
Views: 5468
Reputation: 73731
I had actually implemented a global capture keydown
event listener to stop the propagation of the keydown
events but I had made a mistake identifying the keys. When done correctly, the globalZoneAwareCallback
part of the processing was eliminated (on the right on the image in the question); the globalZoneAwareCaptureCallback
part remained.
The solution is to stop the propagation of the keydown
events in a global event listener which does not itself trigger change detection:
keydown
event (e.g. in a service)window.document.addEventListener
inside NgZone.runOutsideAngular
. This is important because addEventListener
triggers Angular change detection, contrary to what I first thought.this.zone.runOutsideAngular(() => {
window.document.addEventListener("keydown", (event: KeyboardEvent) => {
switch (event.which || event.keyCode) {
case 16:
case 17: {
event.stopPropagation();
break;
}
}
});
});
Thanks to @ashfaq.p and @Nour for the suggestions about NgZone.runOutsideAngular
.
Upvotes: 9
Reputation: 5469
Change detection
in angular works using zone.js
.
zone.js
provides a method called: runOutsideAngularZone()
.
this.zone.runOutsideAngular(() => {
window.document.addEventListener('mousemove', this.mouseMove.bind(this));
});
This will allow you to use events like keydown or keyup / mouse move etc outside of angular change detection.
More about this can be found here: zones in angular
Upvotes: 2