首页 > 解决方案 > Angular 材质 mat-menu 的 Angular 性能问题

问题描述

我在使用 Angular 4 时遇到问题,我有一个组件列表,每个组件内部都有一个 mat-menu(Angular 材料组件)。我在 Chrome 控制台中收到很多警告:

“[违规] 向阻止滚动的‘touchstart’事件添加了非被动事件侦听器。考虑将事件处理程序标记为‘被动’,以使页面更具响应性。”

我已经删除了那个组件,我可以看到警告的数量减少了。你们有谁知道那里发生了什么?触发该警告的 mat-menu 中有什么东西吗?

标签: angularangular-material

解决方案


您使用的是 Angular 4。这是一个非常旧的版本。考虑到 Angular 4 的历史,chrome 中的违规警告相对较新。这意味着较新版本的 Angular 和材质库已更新以防止出现此警告。

您摆脱此警告的唯一方法是降级 chrome 或最终更新您的角度(和材料)版本


如果您无法更新,您可以创建一个事件管理器插件。有了这个,您可以在事件绑定到元素时捕获它们。然而,材料中的事件可能没有以这种方式绑定,而是使用fromEventfrom rxjs 或 standard立即绑定element.addEventListener,但您可以尝试:

在您的 AppModule 中添加此提供程序:

import { EVENT_MANAGER_PLUGINS } from '@angular/platform-browser';

@NgModule({
  providers: [
    {
      provide: EVENT_MANAGER_PLUGINS,
      useClass: PassiveEventsOptionPlugin,
      multi: true
    }
  ]
})
export class AppModule {}

你的事件插件看起来像这样。同样,这是未经测试的:

@Injectable()
export class PassiveEventsOptionPlugin {
  private readonly passiveEvents = [
    'touchstart'
  ];

  constructor(@Inject(DOCUMENT) private doc: any) {}

  supports(eventName: string): boolean {
    return this.passiveEvents.some((event) => eventName.startsWith(event));
  }

  addEventListener(el: HTMLElement, event: string, listener: EventListener): () => void {
    // this is the important part. Adding the passive option
    const options = { passive: true };
    element.addEventListener(type, listener, options);

    return () => element.removeEventListener(type, listener, options);
  }

  addGlobalEventListener(
    element: GlobalEventTarget,
    eventName: string,
    listener: EventListener
  ): () => void {
    let target: EventTarget | undefined;

    if (element === 'window') {
      target = window;
    } else if (element === 'document') {
      target = this.doc;
    } else if (element === 'body' && this.doc) {
      target = this.doc.body;
    }

    return this.addEventListener(target as HTMLElement, eventName, listener);
  }
}

推荐阅读