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?
The keydown event is fired when a key is pressed. Unlike the deprecated keypress event, the keydown event is fired for all keys, regardless of whether they produce a character value. The keydown and keyup events provide a code indicating which key is pressed, while keypress indicates which character was entered.
The simple solution: just use the keyup event (and not the keydown event). This will give you the latest value after the user typed the latest character. That resolves the issue.
The KeyDown event is triggered when the user presses a Key. 2. The KeyUp event is triggered when the user releases a Key. 3. The KeyPress event is triggered when the user presses & releases a Key.
keydown – on pressing the key (auto-repeats if the key is pressed for long), keyup – on releasing the key.
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
.
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With