【问题标题】:HostListener slowing down application: Angular2HostListener 减慢应用程序:Angular2
【发布时间】:2017-07-21 01:17:45
【问题描述】:

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

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

但这会减慢我的应用程序的速度,不是很明显,但页面上的滚动不再流畅。可能是因为 hostlistner 一直在寻找要滚动的页面,所以订阅使整个滚动体验变得迟缓。我尝试删除 hostListner 并且滚动再次平滑。有没有人注意到这种行为?如果没有,使用 Angular2 在页面上订阅滚动事件的最佳方式是什么?

【问题讨论】:

    标签: angular


    【解决方案1】:

    您可以在角度区域之外运行此功能,以防止冗余的变化检测循环。

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

    custom-event-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

    另见

    【讨论】:

    • 不幸的是,这不适用于 Angular 4。我收到此 TS 构建错误,因为 addGlobalEventListener 的定义已更改。
    • 要让它在 Angular 4+ 中工作,请将输入属性 element: HTMLElement 更新为 target: string 或在 angular.io/api/platform-browser/EventManager 中定义
    • 这是非常聪明的答案。覆盖/扩展 Angular 服务/指令的一个问题是,每次更新框架时,您必须记住检查每个扩展类的源代码,以确保内部没有改变!这种方式很容易引入错误
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-11-06
    • 1970-01-01
    • 2014-10-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多