IE11上的Angular 4性能 / CPU使用



我正在处理Angular 4应用程序。它在Chrome&amp上运行良好Firefox但是IE11上的性能是不可接受的。镀铬/FF的路由器变化约为0.5s(更精致的页面),IE11上的变化约为5s。在Chrome/ff上即时打开下拉列表(通过添加/删除CSS类以设置display:none),在IE11上大约需要3秒钟。
打开下拉列表时,IE11剖面图显示了以下内容:
12
时间轴完全充满了classList.add()classList.remove()调用:
12
这是一遍又一遍地添加/删除类的元素。按钮

下拉列表简单地使用[ngClass]指令:

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

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

版本:
角4.4.3
Internet Explorer 11.1884.14393.0

事实证明,问题是文档事件听众太多。

我有一个OnClickoutside指令,该指令注册文档单击"侦听器",并且表中的每个条目都有使用此直接的下拉列表。因此,当我每次点击显示100个条目时,任何地方都会导致100个事件听众开火。

我仅通过单击"单击服务"中的单个文档单击侦听器来优化此功能,仅指令(un-)将元素注册为服务。

这是服务:

/**
 * 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');
  }

最新更新