inocan-group / vue3-google-map

A set of composable components for easy use of Google Maps in your Vue 3 projects.
https://vue3-google-map.com
MIT License
272 stars 54 forks source link

<MarkerCluster>, <CustomMarker> & <InfoWindow> forces re-renders as elements change #90

Open ValiDrv opened 2 years ago

ValiDrv commented 2 years ago

Very similar to issue #84 but different/might shed some light on how to fix.

The map seems to re-render on pretty much any iteration/change. This causes the markers to re-render, and clusters to re-calculate in a loop.

Problem is, it does it even when you interact with something that does not impact it.

Example:

Problem:

Also, if you have allot of markers, the cluster will redraw on what it seems to be every marker dom change, ending up with unresponsive browser pages, and instances where 1000 markers take 10 sec to render. (when in reality they took 0.01 sec, but re-did the math 1000 times)

The same SuperClusterAlgorithm from @googlemaps/markerclusterer works with 100000 markers no problem in other projects (vue2), so that's not the issue. I'm thinking it's some reactivity/watch implementation of this library, but I'm new to vue3 so can't pinpoint it 100%

Replication code: https://stackblitz.com/edit/vitejs-vite-zwxadc?file=src%2FApp.vue

HusamElbashir commented 2 years ago

The same SuperClusterAlgorithm from @googlemaps/markerclusterer works with 100000 markers no problem in other projects (vue2), so that's not the issue.

On the specific issue of a large number of markers there seems to be some perf issues with SuperClusterer in newer versions of googlemaps/markerclusterer. You can refer to this comment https://github.com/inocan-group/vue3-google-map/issues/80#issuecomment-1142462934 for context. Switching to a different algo or pinning that library to an older version might help

ValiDrv commented 2 years ago

I'm 100% sure it's not related to that (SuperClusterAlgorithm math).

Every time something interacts with the GoogleMap.vue, the CustomMarker.vue gets re-rendered so element: customMarkerRef.value can be used in CustomMarker.draw() from /utils/index.js., even if we only need to draw a few of them.

Example: Say we have 4 CustomMarker on screen and 1000 of them total displayed via v-for. When something touches the map, all the 1000 CustomMarkers get rendered, with CSS display: none;, and then the 4 visible ones gets draw() on the screen using this.element which is computed from customMarkerRef.value .

This is what slows it down most the time. Not the SuperClusterAlgorithm math.

On the SuperClusterAlgorithm math tho, It seems that (after a certain number of markers) gets processed every time a CustomMarker renders... so even if it takes something like total time: 6.9951171875 ms, it re-does the same math 1000 times, and we end up with a page frozen for 6.9 sec.

ValiDrv commented 2 years ago

For example: If you hack CustomMarker.vue to use some plain HTML passed to it, instead of use the slot, everything works perfectly, no more lag.

HusamElbashir commented 2 years ago

Yeah maybe we can optimzie how draw is implemented. They have great tips here on the Using custom overlays section: https://cloud.google.com/blog/products/maps-platform/google-maps-platform-best-practices-optimization-and-performance-tips I'll try and dig into that in the coming days

ValiDrv commented 2 years ago

I'll look into it also. But the draw doesn't get called for every marker, only the ones that should show. In my case, it gets called 4 times, but the component renders 1000 times.

mkierdev commented 11 months ago

Same problem here, when we have 1400 points and use MarkerCluser, map freezes for couple of seconds. If we stick to normal Marker, it can render 1400 markers without any issue in few ms.

HusamElbashir commented 11 months ago

@mkierdev you might be able to get better performance by switching to GridAlgorithm

lbineau commented 5 months ago

I confirm this issue, it especially becomes worse with a custom renderer for around 1500 markers. Even using the latest version with the perf improvement https://github.com/inocan-group/vue3-google-map/commit/3feb791828f45066170e89aa94120a3cec36c447 It blocks the UI for 30s. Removing the <MarkerCluster> makes the Map rendering ok without UI blocking. Any idea what could introduce such a performance bummer?