HostListener减慢了应用程序:Angular2

时间:2017-07-21 01:17:45

标签: angular

我有一个hostListner在我的Angular2应用程序中监听scroll事件。我用它来检查用户是否在页面底部滚动并在用户到达页面底部时执行方法。我用以下方式构建了hostlistner:

  @HostListener('window:scroll', [])
  onWindowScroll() {
   const scrolledPercent = /* some logic to calculate the percentage scrolled */
  if ( condition1 && condition2 .... )
    { 
     // doing something here
    }
  }

但这会降低我的应用程序速度,但不是非常重要,但页面上的滚动不再平滑。也许是因为hostlistner一直在寻找要滚动的页面,因此订阅会使整个滚动体验变得迟钝。我尝试删除hostListner,滚动再次平滑。有人注意到这种行为吗?如果没有,使用Angular2在页面上订阅滚动事件的最佳方法是什么?

1 个答案:

答案 0 :(得分:12)

您可以在角度区域外运行此功能,以防止冗余的更改检测周期。

为此,我会覆盖EventManager以使侦听器保持在区域外。

自定义事件-manager.ts

import { Injectable, Inject, NgZone  } from '@angular/core';
import { EVENT_MANAGER_PLUGINS, EventManager } from '@angular/platform-browser';

@Injectable()
export class CustomEventManager extends EventManager {
  constructor(@Inject(EVENT_MANAGER_PLUGINS) plugins: any[], private zone: NgZone) {
    super(plugins, zone); 
  }    

  addGlobalEventListener(element: HTMLElement, eventName: string, handler: Function): Function {
    if(eventName.endsWith('out-zone')) {
      eventName = eventName.split('.')[0];
      return this.zone.runOutsideAngular(() => 
          super.addGlobalEventListener(element, eventName, handler));
    } 

    return super.addGlobalEventListener(element, eventName, handler);
  }
}

<强> app.module.ts

  ...
  providers: [
    { provide: EventManager, useClass: CustomEventManager }
  ]
})
export class AppModule {}

仅通过调用changeDetector.detectChanges

更新视图
@HostListener('window:scroll.out-zone', []) // notice out-zone
onWindowScroll() {
  const scrolledPercent = /* some logic to calculate the percentage scrolled   */
  if ( condition1 && condition2 .... ) { 
      this.cd.detectChanges();
  }
}

<强> Plunker Example

另见