0
votes

I'm using Leaflet + VectorGrid + ngx-leaflet to display vectorial tiles on a map in an Angular app. However when too much points are displayed, scrolling becomes really laggy and impossible. Reducing the number of points improves the situation.

The same scenario works great (plunker) when using simply Leaflet + Vectorgrid, so I believe there are some mouse events being spammed when used with ngx-leaflet. How can I improve the situation? I've reproduced the problem on the demo app from ngx-leaflet but could not make it work with plunker.

1

1 Answers

1
votes

What's likely happening here is that you are adding the VectorGrid layer inside the Angular Zone, which means that Angular is going to monkey patch change detection hooks into all of the registered event callbacks. Basically, you're correct in that all of the mouse events are spamming Angular's change detection.

If you look into the ngx-leaflet core directive, you will see how the map is created outside of the Angular zone. You want to do something similar (I didn't test this, but this should be the right basic idea):

constructor(private zone: NgZone) {}
...
onMapReady(map: any) {
  // noinspection JSUnusedGlobalSymbols
  const vectorTileOptions = {
    vectorTileLayerStyles: {
      "cities-point": (p: any) => this.stylingFunction(p)
    },
    interactive: true
  };


  // Create outside of angular so the events don't trigger change detection
  this.zone.runOutsideAngular(() => {
    L.vectorGrid.protobuf(
      "http://localhost:9999/maps/batimap/{z}/{x}/{y}.vector.pbf",
      vectorTileOptions
    ).addTo(map);
  });
}

The only trick here is that you'll have to manually invoke change detection when you really want Angular to notice a change you've made in a handler registered to one of those events. But, that's fairly standard practice when you're wrapping non-Angular libraries like this. It's the only way to make things work efficiently when you want the automagic of data binding to work.