angular2 google 地图信息窗口打开了很多次,它开始滞后

angular2 google map infowindow opens so many times and it starts lagging

我正在使用 angular-google-map。在项目中,我创建了数百个标记,并且所有标记都共享一个信息 window。下面是模板中的代码:

<div *ngFor="let property of _properties">
  <agm-marker [latitude]="property.Lat"
              [longitude]="property.Lng"
              [iconUrl]="_markerIconUrl"
              (mouseOver)="infoWindow.open();"
              (mouseOut)="infoWindow.close();">
  </agm-marker>
</div>
...
<agm-info-window #infoWindow>
</agm-info-window>

一开始效果很好。但是当我将鼠标悬停在许多标记上时,它开始变慢。这是性能和内存的屏幕截图:

似乎垃圾回收拖慢了页面速度,我真的不知道如何解决它..

我尝试了这些:

  1. 我认为可能是 mouseover/mouseout 发射器减慢了速度。但是,如果我将 infoWindow.open() 替换为其他函数,它就可以正常工作。
  2. 然后我查看了angular-google-map源码,发现infoWindow.open():
  open(infoWindow: AgmInfoWindow): Promise<void> {
    return this._infoWindows.get(infoWindow).then((w) => {
      if (infoWindow.hostMarker != null) {
        return this._markerManager.getNativeMarker(infoWindow.hostMarker).then((marker) => {
          return this._mapsWrapper.getNativeMap().then((map) => w.open(map, marker));
        });
      }
      return this._mapsWrapper.getNativeMap().then((map) => w.open(map));
    });
  }

我认为可能是 Promise 减慢了速度,但是当我注释掉 w.open(map) 和 w.open(map, marker) 时它工作正常。

所以我认为问题可能是因为它多次调用 w.open(map)?我发现open函数来自Google Map API infoWindow。我尝试清除内容并设置 infoWindow conent='' 并每次都关闭它,但仍然无法修复它。

我终于修好了。由太多更改检测引起的问题。我在这里找到了解决方案:https://github.com/angular/angular/issues/10883#issuecomment-240423378
我所做的是在 Angular 之外调用 infowindow.open() 以避免更改检测:

map.component.html

<div *ngFor="let property of _properties">
  <agm-marker [latitude]="property.Lat"
              [longitude]="property.Lng"
              [iconUrl]="_markerIconUrl"
              (mouseOver)="_infoWindowOpen($event, infoWindow);"
              (mouseOut)="_infoWindowClose($event, infoWindow);">
  </agm-marker>
</div>
...
<agm-info-window #infoWindow>
</agm-info-window>

map.component.ts

import { Component, OnInit, NgZone } from '@angular/core';
...
constructor(private _zone: NgZone) {...}
...
  private _infoWindowOpen(mouseEvent: any, infoWindow: any) {
    infoWindow.hostMarker = mouseEvent.marker;
    this._zone.runOutsideAngular(() => {
      infoWindow.open();
    });
  }
...
  private _infoWindowClose(mouseEvent: any, infoWindow: any) {
    this._zone.runOutsideAngular(() => {
      infoWindow.close();
    });
  }