【问题标题】:Angular 4 performance / CPU usage on IE11IE11 上的 Angular 4 性能/CPU 使用率
【发布时间】:2018-03-29 21:40:25
【问题描述】:

我正在开发一个 Angular 4 应用程序。它在 chrome 和 firefox 上运行良好,但在 IE11 上的性能加载时间是不可接受的。 Chrome/FF 上的路由器更改大约为 0.5 秒(对于更详细的页面)和 IE11 上的大约 5 秒。在 Chrome/FF 上打开下拉菜单(通过添加/删除 CSS 类来设置 display:none)是即时的,在 IE11 上大约需要 3 秒。
打开下拉列表时,IE11 分析器显示以下内容:
1 2
并且时间线完全充满了classList.add()classList.remove() 电话:
1 2
一遍又一遍地添加/删除类是同一对元素。按钮

下拉列表仅使用[ngClass] 指令:

  <div class="dropdown-menu"
       [ngClass]="{
       'show': open,
       'mod-dropup': dropup,
       'mod-right': rightAlign
       }">
    <ng-content></ng-content>
  </div>

我在 polyfills.ts 中添加了所有必需的 polyfill。这可能是什么原因?

版本:
Angular 4.4.3
Internet Explorer 11.1884.14393.0

【问题讨论】:

  • 你有想过这个吗?面临同样的问题....
  • 很遗憾没有。

标签: angular performance internet-explorer-11


【解决方案1】:

原来问题是文档事件监听器太多。

我有一个 onClickOutside 指令,它注册了一个文档点击侦听器,并且表中的每个条目都有一个使用该指令的下拉列表。因此,当我在任何地方显示 100 个条目时,每次单击都会触发 100 个事件侦听器。

我通过在点击服务中仅使用单个文档点击侦听器来优化这一点,并且指令仅(取消)向服务注册元素。

这里是服务:

/**
 * A event emitter that should be notified about some kind of click related to the element
 */
export interface ClickListener {
  element : ElementRef;
  emitter : EventEmitter<Event>;
}

/**
 * A central service for managing click handlers
 * This is mainly an optimization to reduce the amount of global click event handler
 */
@Injectable()
export class ClickService {

  private clickOutsideListeners : ClickListener[] = [];

  constructor() {
    this.registerClickHandlers();
  }

  private registerClickHandlers() : void {
    document.addEventListener('click', (event : Event) => {
      this.handleClickOutside(event);
    });
  }

  /**
   * Emits for every registered callback if the click is outside of the element
   */
  private handleClickOutside(event : Event) : void {
    this.clickOutsideListeners
      .filter(entry => !entry.element.nativeElement.contains(event.target))
      .forEach(entry => {
        entry.emitter.emit(event);
      });
  }

  /**
   * Registers a listener to be notified whenever there is a click outside of the element
   */
  public addOutsideClickListener(element : ClickListener) : void {
    if (this.clickOutsideListeners.indexOf(element) !== -1) return;
    this.clickOutsideListeners.push(element);
  }

  /**
   * Unregisters the listener
   */
  public removeOutsideClickListener(element : ClickListener) : void {
    const index = this.clickOutsideListeners.findIndex(entry => entry === element);
    if (index === -1) return;
    this.clickOutsideListeners.splice(index, 1);
  }
}

指令:

/**
 * Emits a event when there has been a click outside of the host element
 */
@Directive({
  selector: '[mdeOnClickOutside]',
})
export class OnClickOutsideDirective implements OnInit, OnDestroy {

  @Output() mdeOnClickOutside : EventEmitter<Event> = new EventEmitter();

  /**
   * (Un-)registers a click listener with the global click service
   */
  @Input() set mdeOnClickOutsideActive(active : boolean) {
    this.inputReceived = true;
    const clickCallback = {
      element: this.element,
      emitter: this.mdeOnClickOutside,
    };
    if (active) {
      this.clickService.addOutsideClickListener(clickCallback);
    } else {
      this.clickService.removeOutsideClickListener(clickCallback);
    }
  }

  private inputReceived : boolean;

  constructor(private element : ElementRef, private clickService : ClickService) {
  }

  /**
   * Activates click listener if it has not explicitly been set
   */
  ngOnInit() : void {
    if (this.inputReceived) return;
    this.mdeOnClickOutsideActive = true;
  }

  ngOnDestroy() : void {
    this.mdeOnClickOutsideActive = false;
  }

}

然后在其他一些组件的模板中像这样使用它:

<div (mdeOnClickOutside)="clickOutside()">Something</div>

组件中的函数:

clickOutside() {
    console.log('Somebody clicked somwhere outside');
  }

【讨论】:

  • 嗨,Manuel,您可以分享您创建的服务吗?我被困在同一个状态.....谢谢
  • 您使用了哪个下拉菜单?角材料?
  • @ShaulNaim 我们使用引导 CSS 构建了一个自定义下拉组件 - 但这不会影响这篇文章中的性能问题
  • 谢谢,问题是我正在使用 ngx-bootstrap,并且在 ie11 上打开下拉菜单时的性能非常慢,需要 6 秒才能打开......我意识到这是因为我有行动每一行的下拉菜单,他们都监听 body 上的点击事件,而 IE 不能很好地处理它......我怎样才能覆盖引导行为或者我应该实现一个自定义下拉菜单你能建议吗?谢谢。
猜你喜欢
  • 1970-01-01
  • 2016-08-02
  • 1970-01-01
  • 1970-01-01
  • 2018-01-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多