Angular-google-maps: Change Detection runs all time even if map is not present

Created on 15 May 2017  路  9Comments  路  Source: SebastianM/angular-google-maps

The issue is than if you have <agm-map> in component with *ngIf on it, the change detection runs every second after it is shown.

Steps to reproduce and a minimal demo of the problem

I created repo for reproduction.

_What steps should we try in your demo to see the problem?_

  1. Clone the repo.
  2. Put your API_KEY to app.module.ts.
  3. Run with ng serve
  4. Open the console window.
  5. Click on Show/Hide button - Map hides and change detection runs only couple of times and then stops
  6. Click on Show/Hide button again - Map is shown and in console the change detection logs keep running / there is also so much change detection running if you hover over

angular2 & angular-google-maps version

"@agm/core": "1.0.0-beta.0"

stale

Most helpful comment

@SebastianM

I believe I tracked down where this issue is coming from. In the constructor for FitBoundsService, there's an observable pipeline definition which basically samples the includeInBounds$ observable based on a variable timer, and then maps that onto a generation of the bounds.

The first problem is the internal timer is triggering angular change tracking every time it fires (by default, 5 times per second) regardless of whether the observable it's sampling has a new value.

The second is that the FitBoundsService is not disposed on map-hide, but a new instance is created the next time the map is shown. This leak leads to very bad performance if change checking is remotely expensive.

I'm fairly new the RxJS and the Angular change-tracking system, so I'm not at all sure what the appropriate fix is here. Hopefully finding the problem will make this easy for someone more skilled than me.

All 9 comments

Thank you @efstathiosntonas I will try that. But I think that this is still a bug, because it should not trigger so much ChangeDetection even if the map component is hidden.

Any update on this issue?

I think we are experiencing this issue as well. I suspect some subscriptions are not being unsubscribe()'d somewhere in the map. In our application, if you:

  • visit a page that renders a map
  • leave the page so it gets destroyed
  • visit again
  • click on the map

We get a runaway number of calls to ngDoCheck() in the app component, and noticeable performance hit:

2017-06-07 at 12 14 51 pm

2017-06-07 at 11 53 39 am

This occurs even when I take off (mapClick) from the sebm-google-map element.

I tried to recreate this in a plunkr. I haven't been able to get a runaway number of digest loops after hiding -> showing -> clicking the map yet. But I did notice that the 2nd time the map renders it triggers a digest check every time you move your mouse, _in firefox only_... Seems like related behavior, maybe.

2017-06-07 at 1 22 33 pm

This issue still exists in 2018. I was able to replicate it on mobile safari and chrome, I've added a ngDoCheck on app component like @ratbeard did and used Vorlon.JS to remotely debug the app from the mobile device...

Hi @SebastianM, any thoughts on this?

I think i've found the problem.
Basically GoogleMapsAPIWrapper::subscribeToMapEventmethod creates map listeners but never destroys them when AgmMap component is destroyed.
Keeping Google Maps events appended seems to trigger Angular change detection like crazy

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

@SebastianM

I believe I tracked down where this issue is coming from. In the constructor for FitBoundsService, there's an observable pipeline definition which basically samples the includeInBounds$ observable based on a variable timer, and then maps that onto a generation of the bounds.

The first problem is the internal timer is triggering angular change tracking every time it fires (by default, 5 times per second) regardless of whether the observable it's sampling has a new value.

The second is that the FitBoundsService is not disposed on map-hide, but a new instance is created the next time the map is shown. This leak leads to very bad performance if change checking is remotely expensive.

I'm fairly new the RxJS and the Angular change-tracking system, so I'm not at all sure what the appropriate fix is here. Hopefully finding the problem will make this easy for someone more skilled than me.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

ChrisDevinePimss picture ChrisDevinePimss  路  3Comments

PeterSisovsky picture PeterSisovsky  路  3Comments

shedar picture shedar  路  4Comments

DeveloperAdd007 picture DeveloperAdd007  路  3Comments

Subhojit1992 picture Subhojit1992  路  3Comments