I am placing ~600 markers on a map with info windows. I do this with an *ngFor that gets filled by a subscription.
If I don't update the markers, it works at a reasonable rate. If I do add in markers, it takes 21 seconds to load the page.
@haburka Would you mind please forking this plunk and reproducing the problem there so we can better assist you? Thanks!
@haburka @alexweber Hi. I have the same problem but my case is 5,000 markers on a map. I created the plunk page that place 600 markers and there is no problem.
I think this problem has something to do with contents of info windows.
When I run the plunk, it takes about 6-7 seconds to fully load, which is incredibly slow compared to vanilla google maps. At your scale, I'm sure it takes much longer.
When I profile, it tells me that the app is mostly spending CPU time detecting changes. Perhaps this is an issue with angular 2 itself? When you have so many data bindings I'm sure just about anything can get very slow.
Hi I have the same problem here trying to visualise ~7000 markers,
I'think @TSHiYK is right, the problem comes up when using info windows.
I'll try to get deeper into the problem spec as soon as I can
@haburka @Tolomeo I set a custom component instead of sebm-google-map-marker and use the GoogleMapsAPIWrapper to get the instance of it as the one used by the map. Then I use a setMap method of original google map API and It takes 1-2 seconds to load 5,000 markers at my condition.
hey guys, check out this issue
https://github.com/angular/angular/issues/10883#issuecomment-240423378
I think some events should be run outside of Angular. E.g. you probably don't need to run change detection on scroll evt. etc.
Personally, I use Leafletjs and there is the same problem so I isolate the whole lib and only trigger change detection on particular events.
But for library authors it's pain! Maybe good documentation can help, but...
@otodockal cool, wrote the same about Zones a few minutes ago here 馃樃 https://github.com/SebastianM/angular2-google-maps/issues/579#issuecomment-242479924
I have three features in my mind that we should add:
1) Switch to ChangeDetectionStrategy.OnPush - this should be simple
2) Refactor the *Manager Services that they work with an Interface rather than a certain Component (for example SebmGoogleMapMarker). Then everyone can add a custom marker implementation (for example) and use the existing managers).
3) Introduce new directives for rendering a huge amount of markers/infoWindows/etc.
<sebm-google-map-markers [markers]="myMarkersArray"></sebm-google-map-markers>
I did some profiling today to find out where's the bottleneck. The one thing that @otodockal described here (instantiating the google.Map inside the zone) is not a real performance problem.
The real problem is the huge amount of mouse and position listeners. But you can get a huge performance improvement with this method:
Here's a quick comparison between the two ChangeDetection modes for the following map component - it creates 15,000 polylines with each two points:
import { Component, OnInit, ChangeDetectionStrategy } from '@angular/core';
@Component({
selector: 'ad-comp-1',
template: `
<sebm-google-map [latitude]="5" [longitude]="32" [zoom]="3">
<sebm-google-map-polyline *ngFor="let a of numbers" [attr.id]="a">
<sebm-google-map-polyline-point [latitude]="5+(a/100)+0.3" [longitude]="32+(a/100)">
</sebm-google-map-polyline-point>
<sebm-google-map-polyline-point [latitude]="5+(a/100)+0.5" [longitude]="32+(a/100)+0.3">
</sebm-google-map-polyline-point>
</sebm-google-map-polyline>
</sebm-google-map>
`,
styleUrls: ['./comp-1.component.css']
})
export class Comp1Component {
lat = 4;
lng = 30;
checks = 0;
numbers = [];
constructor() {
for(let i = 10; i < 15000; i++) {
this.numbers.push(i);
}
}
}
1) ChangeDetectionStrategy.Default for the component that has the map:
When you drag the map, you will recognize some little lags.
Here are the profiling stats of ng.profiler.timeChangeDetection({record: true});:
ran 5 change detection cycles
2016-11-18 14:19:51.557 common_tools.js:84 192.82 ms per check

This is of course really slow :)
2) Now let's change the ChangeDetectionStrategy to OnPush:
Here are the stats:
ran 28305 change detection cycles
2016-11-18 14:26:43.070 common_tools.js:84 0.02 ms per check

This is a huge improvement in performance (because the change detection doesn't run on every event outside the component). So this is quick win if you have thousands of components
<-- for example--->
<sebm-google-map [listenForDragEvents]="true" [listenForMouseEvents]="true">
</sebm-google-map>
// cc @haburka @alexweber @Tolomeo @otodockal
up
I only have ~200 points, and with ChangeDetectionStrategy.OnPush the map loads and runs smooth until I start clicking on info windows. I'm using the [isOpen] binding to keep only one info window open at a time and with each new info window I click on the CPU continues to increase. After about 6-7 it's around 80% and stays there even with all info windows closed.
Is that what you were referring to in your point 1 that Info Windows were a special case? As in, OnPush doesn't help here?
Most helpful comment
I did some profiling today to find out where's the bottleneck. The one thing that @otodockal described here (instantiating the google.Map inside the zone) is not a real performance problem.
The real problem is the huge amount of mouse and position listeners. But you can get a huge performance improvement with this method:
Profiling
Here's a quick comparison between the two ChangeDetection modes for the following map component - it creates 15,000 polylines with each two points:
1) ChangeDetectionStrategy.Default for the component that has the map:
When you drag the map, you will recognize some little lags.
Here are the profiling stats of
ng.profiler.timeChangeDetection({record: true});:This is of course really slow :)
2) Now let's change the ChangeDetectionStrategy to OnPush:
Here are the stats:
This is a huge improvement in performance (because the change detection doesn't run on every event outside the component). So this is quick win if you have thousands of components
Possible improvements
Long story short: Use ChangeDetectionStrategy.OnPush for your components that use <sebm-google-map>
// cc @haburka @alexweber @Tolomeo @otodockal