react-native-maps: Custom marker in google map causes high CPU load on iOS

Even if there is only one custom marker in google map, the app uses a LOT of CPU on iOS. It happens on both simulator and device with debug/release builds.

You can see in the screenshot of the demo project I made, when we use custom marker, the CPU usage jumps from 0.8% to 62%. I also tried creating a custom marker in a native iOS app using Google Maps SDK for iOS. It does not use much CPU.

The following two ways of defining a custom marker do not make any difference. Both of them use a lot of CPU.

<MapView.Marker coordinate={coordinate} anchor={{x: 0.65, y: 1}}>
  <Image source={imageSrc}/>
</MapView.Marker>
<MapView.Marker coordinate={coordinate} anchor={{x: 0.65, y: 1}} image={imageSrc}/>

Screenshot

I tried to use Instruments to profile the app. For unknown reason, something (the custom marker i guess) keeps redrawing.

Screenshot

Environment: react-native-maps: 0.13.0 react-native: ^0.40.0 map provider: google OS: iOS

Another person encountered the same issue. https://github.com/airbnb/react-native-maps/issues/741#issuecomment-263400988

About this issue

  • Original URL
  • State: closed
  • Created 7 years ago
  • Reactions: 39
  • Comments: 61 (15 by maintainers)

Commits related to this issue

Most upvoted comments

FYI noticed that disabling tracksViewChanges on the _realMarker in AIRGoogleMapMarker.m seems to resolve the CPU. It adds some rendering quirks for our implementation, so still working on a complete solution. Wanted to throw it out there in case someone with more expertise can add to it.

Setting tracksViewChange to false works for static markers but requires a lot of workarounds for dynamic re-rendering of markers, so it cannot be considered as ‘official’ fix…

I’ve opened an issue on Google’s issue tracker for this: https://issuetracker.google.com/issues/111711319

For version “0.24.2”, we can use prop “icon” instead of “image” to fix the issue

Hi there, so setting tracksViewChanges to false, doesn’t render some of my markers, how can I manage tracksViewChanges properly ??

Setting tracksViewChanges to false statically seems to cause a race condition in my app, where sometimes (~20% of instances) only a fraction of the markers render.

I’m not sure on the best way, but here is what I do. I have a marker Component that renders <MapView.Marker> with tracksViewChanges set to true.

On ComponentDidUpdate I set a timeout of 400ms and set tracksViewChanges to false.

I set trackViewChanges again to true when the component is receiving props. Once the component rerenders the componentDidUpdate is triggered again and after 400ms the tracksviewChanges is set to false again.

This works for me. If anyone knows a better way… please share.

If it helps, the high CPU issue also occurs when using a MapView.Marker with an image set.

My steps:

  1. Launch app with PROVIDER_GOOGLE on iOS without any markers etc, just the map. CPU about 100%
  2. Add 1-5 custom marker(s). CPU about 65%
  3. Remove all custom markers - everything is fine. CPU about 2%

Also:

  1. I tried to use image prop instead of custom marker - the same result - at start CPU about 100%, after all custom markers were removed - CPU about 65%
  2. I tried to use icon prop - everything is fine, if I do not moving the map - CPU about 2%

But I cannot use icon prop because I really need to set different width/height depends on business logic.

I have: react-native: 0.61.2 react-native-maps: 0.27.1

@aksonov - can you share some code? In our case tracksViewChanges set to false after 0.4s seems to do miracles and our map only uses high cpu during the initial rendering of the markers.

I also noticed that even if you have a single marker on the map - if trackViewChanges is set to true, then the CPU is high… It seems that it doesn’t matter if you have 1 or 100 markers - if trackViewChanges is set to true, then you are going to have high CPU usage.

I fixed this by exposing the google maps icon marker property to RN (using the patch from #1491). In the majority of use cases (i.e. you just want a custom marker image) this is sufficient, and much simpler to boot.

I also think that it’s not really nice to have the app consume 100% CPU for some fraction of a second, whether that’s a hard timeout or the delay between componentDidMount and onMapReady firing…

@compojoom Works well, thanks! But I’m not sure it is good fix and looks like react-native-maps Marker could do this (setting tracksViewChanges true/false depending from update state) by itself

Whats the difference between an icon and an image?

Answer: image prop in Marker is an icon, Image is an image.

This occurs when component is not updating and after the map has loaded in.

I’m running on an iPhone 6 simulator.

Apple Google
CPU with MapView.Marker 0% 99%
CPU without MapView.Marker 0% 1%

Google is the better option (and styles!) but the CPU issue makes it unusable 😦

This is my Marker

<MapView.Marker.Animated coordinate={this.props.coordinate} anchor={{ x: 0.5, y: 0.5 }}>
  <Image source={require('./my_location.png'} style={{ width: 12, height: 12 }} />
</MapView.Marker.Animated>

stinju’s fix worked