flutter / flutter/flutter

[Feature] Improve google_maps_flutter performance with large datasets by allowing imperative map updates

Open
#146,041 7 comments 9 reactions 0 assignees View on GitHub
c: new feature c: proposal p: maps P2 package team-ecosystem triaged-ecosystem
Dominant language
Dart
Stars
179k
Forks
31.1k
PR merge metrics
PR metrics pending

Description

### Use case

Hello, here is my use case below around a performance issue I have encountered, that this new feature would resolve.

An app displaying a map with thousands of elements (markers, polylines, polygons, circles) on it, where the user can select filters to make elements show / hide / change while keeping a continuous 60 FPS smooth UX.

This is not possible today in the current state of the google_maps_flutter library, for example:

* for markers, you need to use the `markers` parameter of the `GoogleMap` widget
* if you go from 0 markers on the map to 3000, then you need to update the `markers` parameter from an empty list to a 3000 items list, which will consequently freeze the UI for a noticeable amount of time (over a full second on some devices)
* if you have 3000 markers on the map and want to modify just one marker (e.g. change its color/icon when clicked to visually "select" it), then the update of that one marker takes a significant amount of time (more than a few frames on most devices) because even though you updated a single marker, you still need to pass the list of 3000 and those lists need to be re-compared to make a smart delta update of a single marker

Even though declarative handling is very well implemented google_maps_flutter, the declarative approach has its limits in use cases like this one, where having the ability to imperatively update the map objects is needed.

### Proposal

I would like the google_maps_flutter library to allow updating map objects imperatively, through the `GoogleMapController` for example.

I have addressed my use case by implementing a modified version of google_maps_flutter where it is possible to update map objects imperatively instead of declaratively, you can find the code [here](https://github.com/androidseb/packages/compare/main...androidseb:packages:mod/gmf_imperative_map_updates) - in this alternative implementation:

* map object updates are throttled and queued to no more than a few per frame so the UI thread is never frozen by map updates
* updating 3000 markers might take several seconds where you'll see markers pop on the screen gradually rather than in one shot
* this is slower than updating all 3000 at once, but the UI remains smooth and responsive the whole time
* the UI state is eventually consistent
* from a user's perspective, this almost looks like an animation of markers appearing / loading

I have been using this in my production app with over ~30k daily active users since about March 2023 and so far it has been working great - note that I was using a closed source modified version of `google_maps_flutter: 2.2.4`, I've open-sourced this link above recently while upgrading my Google Maps library dependencies, I'll be using that github fork for now as a dependency in the meantime.

This works for my use case, but it is a minimal implementation just for me so it no longer allows to declaratively update markers / polylines / polygons / circles - a full implementation would allow both declarative and imperative, reserving the imperative approach for specific use cases requiring it.

I might be interested to invest more into this implementation if it has a chance of being merged back to the main `google_maps_flutter` library, please let me know if this is a feature you might want to add in - but if it is deemed too much of an edge case I would understand.

Thanks.

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.