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>
一开始效果很好。但是当我将鼠标悬停在许多标记上时,它开始变慢。这是性能和内存的屏幕截图:
似乎垃圾回收拖慢了页面速度,我真的不知道如何解决它..
我尝试了这些:
- 我认为可能是 mouseover/mouseout 发射器减慢了速度。但是,如果我将 infoWindow.open() 替换为其他函数,它就可以正常工作。
- 然后我查看了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();
});
}
我正在使用 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>
一开始效果很好。但是当我将鼠标悬停在许多标记上时,它开始变慢。这是性能和内存的屏幕截图:
似乎垃圾回收拖慢了页面速度,我真的不知道如何解决它..
我尝试了这些:
- 我认为可能是 mouseover/mouseout 发射器减慢了速度。但是,如果我将 infoWindow.open() 替换为其他函数,它就可以正常工作。
- 然后我查看了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();
});
}