gpt4 book ai didi

javascript - 为什么一个 RxJS Subject 比多个事件监听器更快?

转载 作者:可可西里 更新时间:2023-11-01 01:34:44 25 4
gpt4 key购买 nike

我最近发现页面的性能受到在其模板上多次使用的 Angular Directive(指令)的极大阻碍。在以下代码中找到了性能较慢的原因:

@HostListener('window:keydown', ['$event'])
private keydown(e: KeyboardEvent) {
this.doSomething(e);
}

我怀疑问题可能是由于在窗口按键事件上注册了多个事件监听器引起的,因为每次在页面上重复该指令时都会注册一个新的事件监听器。为了验证该理论,我创建了一个带有 RxJS 主题的服务来处理该键盘事件:

@Injectable()
export class KeyboardService {
constructor() {
window.addEventListener('keydown', event => {
this.keydownSubject.next(event);
});
}
}

private keydownSubject: Subject<KeyboardEvent> = new Subject<KeyboardEvent>();

get keydown(): Observable<KeyboardEvent> {
return this.keydownSubject.asObservable();
}

然后我删除了指令中的@HostListener,并在 ngOnInit 中订阅了该服务的主题:

export class KeydownEventDirective implements OnInit, OnDestroy {
constructor(private keyboardService: KeyboardService) {}

private keydown(e: KeyboardEvent) {
this.doSomething(e);
}

private keydownSubscription: Subscription;
ngOnInit() {
this.keydownSubscription =
this.keyboardService.keydown.subscribe(e => {
this.keydown(e);
});
}

ngOnDestroy() {
this.keydownSubscription.unsubscribe();
}

...
}

该解决方案加快了页面速度,我很难发现为什么会这样。为什么 @HostListener 或向窗口的 keydown 事件添加多个事件监听器比对 RxJS Subject 的多个订阅对页面性能的影响更大?会不会是 Angular HostListeners 默认情况下不是被动监听器?

最佳答案

答案在于 Angular 对 Zone.js 的使用。 Angular 使用 Zone.js 进行变化检测。有关 Zone.js 如何工作的信息,我推荐 thoughtram.io 文章,Understanding ZonesZones in Angular .

最初的问题是在每次击键时页面的性能中发现的。为什么事件不能有效地处理它?问题出在 Angular 的变化检测上。 Zone.js 猴子用自己的函数修补 DOM 事件监听器注册。 Angular 利用了这一点,使每个带有监听器的 DOM 事件也触发更改检测。

当重复组件的多个实例在窗口上各自有自己的 @HostListener 时,它们各自独立触发 Angular 的变更检测。这导致 Angular 尝试检查整个应用程序,以检查每个监听键盘事件的组件在每次击键时的变化。考虑到这一点,出现性能问题也就不足为奇了。

KeyboardService 解决了这个问题,因为它只触发一次更改检测。只有一个监听器,RxJS Subject 将事件同步传递给单个 Zone.js 执行中的每个组件的订阅。

关于javascript - 为什么一个 RxJS Subject 比多个事件监听器更快?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45643327/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com