0

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

<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. 我认为它可能是鼠标悬停/鼠标悬停发射器减慢了它的速度。但是如果我将 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='' 并每次关闭它,但仍然无法修复它。

4

1 回答 1

2

我终于修好了。更改检测过多导致的问题。我在这里找到了解决方案: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();
    });
  }
于 2017-11-28T03:49:23.697 回答