googlemaps / android-maps-compose

Jetpack Compose composables for the Maps SDK for Android
https://developers.google.com/maps/documentation/android-sdk/maps-compose
Apache License 2.0
1.14k stars 135 forks source link

Map initialization with desired configuration is delayed #491

Open bubenheimer opened 8 months ago

bubenheimer commented 8 months ago

Setting an initial camera position for the GoogleMap is commonly done by passing an appropriately initialized CameraPositionState parameter to the GoogleMap() Composable.

While reviewing the android-maps-compose code (4.3.0) I noticed that the GoogleMap camera is moved to its initial requested position (via CameraPositionState) only during the (sub-) composition apply phase. I believe this means that the entire initial sub-composition (short of applying) has to complete first. I think this could mean a significant delay in map position initialization, in particular if the sub-composition is fairly sizable.

Delaying map position initialization implies that loading tiles for the desired position is delayed. It would also mean additional visual artifacts, such as missing tiles and visually changing the map center from (0.0, 0.0) to the desired camera location.

From looking at the code I think it would be fairly easy and trouble-free to preempt the delay. The desired position is readily available before initializing the subcomposition and can be set right after awaitMap() has returned.

In terms of correctness, the parent composition would have completed at this point already, so the information from CameraPositionState can be considered valid/committed. I would expect that at this point the MapView would start being rendered, so the initial camera position should be set pronto.

Does this make sense? Looking for feedback.

https://github.com/googlemaps/android-maps-compose/blob/4b7967d15f8add4589e7d02cf8bf71f1c594f59d/maps-compose/src/main/java/com/google/maps/android/compose/GoogleMap.kt#L158-L168

https://github.com/googlemaps/android-maps-compose/blob/4b7967d15f8add4589e7d02cf8bf71f1c594f59d/maps-compose/src/main/java/com/google/maps/android/compose/GoogleMap.kt#L126-L129

bubenheimer commented 8 months ago

The delay in setting initial CameraPosition was first introduced in 2237950. Up until then setting the camera was prompt.

I see now that this problem is not just about the camera. There is other critical map configuration from MapProperties that is similarly delayed and could cause temporary visual artifacts, slowness, etc.: contentPadding and various MapProperties such as mapType.

These additional concerns would likely require more substantial changes. Their introduction stems from the same commit.

mishackee commented 4 weeks ago

Is there some workaround/update for this please? It makes maps in lazy lists quite unappealing.

bubenheimer commented 4 weeks ago

@mishackee the concern I brought up in this issue is of a more theoretical and architectural nature, I have not quantified it.

Reusing GoogleMap() inside a lazy list is optimized in current android-maps-compose releases to leverage ReusableComposition. As long as your code does not preclude reusing the GoogleMap() things should not be overly slow.

mishackee commented 4 weeks ago

@bubenheimer Thanks for the prompt response. My bad, sorry, it seems to work in lazy lists once the map is initialized. However, adding it to the composition for the first time, the map is in some initial state and then jumps to my initial CameraPositionState. Is the delay configuration a possible cause of that? And if it is, is there a workaround for that now?

bubenheimer commented 4 weeks ago

@mishackee thank you for adding this valuable detail. It is the type of behavior I would expect to see with this issue. However, a jump like that could also be caused by initializing CameraPositionState in a suboptimal manner. I am not aware of other reports of jumpy initialization behavior at this time. Can you post excerpts of your code showing how you initialize CameraPositionState and how you pass it into the GoogleMap()? There may be something else delaying CameraPositionState initialization to a later composition.

As for a workaround, the problem should be more tolerable in R8/Proguard-optimized release builds, baseline profiles would likely help as well. See if this takes care of it.