react-native-maps: Custom Markers cause extreme lag and slow down on android

Is this a bug report?

Yes

Have you read the Installation Instructions?

Yes

Environment

“expo”: “^32.0.0”, “react”: “16.5.0”, “react-native”: “https://github.com/expo/react-native/archive/sdk-32.0.0.tar.gz”,

Expo SDK32 utilises “react-native-maps”: 0.22.1 “react-native-svg”: 8.0.10

Steps to Reproduce

This has only been an issue since updating Expo SDK from 30 to SDK 32. In that time expo updated rn maps from 0.21.0 to 0.22.1. My main page is a full screen mapview with about 10-100 custom markers. If the map initialises with more than 10 markers the entire app runs extremely slow on android (only appears to effect android).

Behavior

In previous versions my app functioned well on android and iOS. After updating expo and rn maps even navigating away from the map will cause delays of 5-10 seconds to register a click. Spinner animations become clunky and the map becomes almost unusable as complex gestures aren’t registered. Below is an example of a circle marker (I use more complex markers but even this will result in the same slow down). To compare, changing the SVG image to a png in the image prop fixes the lag problem but would be unusable in all but the most basic use cases.

Reproducible Demo

The following marker causes extreme lag on android. In fact any child in the Marker component cases lag.

<MapView.Marker
          coordinate={{latitude: marker.latLng.lat, longitude: marker.latLng.lng}}
          key={marker.id + moment().unix()}
          anchor={{x: 0.5, y: 0.5}}
           onPress={()=> this.props.showModal({marker}, 'markerModal')}
          >
            <Svg height={20} width={20}>
              <Svg.Circle
                cx="10"
                cy="10"
                r={2}
                fill={this.markerType(marker)}
              />
            </Svg>
          </MapView.Marker>

The following in an example of what works without lag but in some use cases I need to show custom text and direction arrows so this isn’t enough

        <MapView.Marker
          coordinate={{latitude: marker.latLng.lat, longitude: marker.latLng.lng}}
          key={marker.id + moment().unix()}
          anchor={{x: 0.5, y: 0.5}}
          onPress={()=> this.props.showModal({marker}, 'markerModal')}
          image={require('../../assets/icons/circle.png')}
          />

About this issue

  • Original URL
  • State: closed
  • Created 5 years ago
  • Reactions: 37
  • Comments: 39 (3 by maintainers)

Most upvoted comments

I am too encountering this behaviour since Upgrading from Expo SDK 30 to 32. It seems like setting prop tracksViewChanges={false} on the MapView.Marker component fixes the performance issues.

I resolved this issue by turning on and off tracksViewChanges as @skidr0w said. #1031 was helpful to me.

Now my customMarker class looks like this:

state = {
  tracksViewChanges: false,
}

componentDidUpdate(prevProps) {
    if (prevProps.coordinate !== this.props.coordinate // set true only when props changed
        || prevProps.value !== this.props.value 
        || prevProps.level !== this.props.level) {
        this.setState({tracksViewChanges: true})
    } else if (this.state.tracksViewChanges) {
       // set to false immediately after rendering with tracksViewChanges is true
        this.setState({tracksViewChanges: false})
    }
}

render() {
  return (
    <MapView.Marker
        coordinate={coordinate}
        style={{ zIndex: isFocused ? FOCUSED_MARKER_ZINDEX : zIndex }}
        onPress={onPressMarker}
        tracksViewChanges={this.state.tracksViewChanges}
    >
      ...
   </MapView.Marker>
}

Now google map at android response very very fast. I am using Svg to draw marker at Android and View to draw one at iOS.

I’ve encountered the same issue.

The same application use less CPU with react-native-maps v0.21.0 than v0.22.1.

Also 26 custom markers are shown faster on v0.21.0.

The following image shows CPU usage when the app running with react-native-maps v0.22.1 on emulator: new rn map-cpu usage

The following image shows CPU usage when the app running with react-native-maps v0.21.0 on emulator: old version of rn maps with modified drawee-cpu usage

My laptops cpu-fan never stops when running v0.22.1 and this may cause drain phone battery faster.

This is a big issue.

cc: @rborn @alvelig

I am too encountering this behaviour since Upgrading from Expo SDK 30 to 32. It seems like setting prop tracksViewChanges={false} on the MapView.Marker component fixes the performance issues.

I tried that. However, markers are located in at wrong places. That is, if there are 100 markers on the map, and if I move map to the left, all the markers have to move correspondingly. However, if tracksViewChange is false, markers does not move as map moves.

iOS works well without specifying tracksViewChange.

@RWOverdijk @oshtman key={marker.id + moment().unix()} This creates a new marker every time instead of re-rendering. (constructor calls again rather then ComponentWillRecieveProps). I think we should use this key={marker.id} as a key. Let’s try with this and see.

This is working quite well for us: (credits to https://github.com/davidhellsing / https://github.com/react-native-community/react-native-maps/issues/369#issuecomment-340334468)

import React, {PureComponent} from "react"
import {MapView} from "expo"
import isEqual from "lodash.isequal"
import PropTypes from "prop-types"


export default class MapMarker extends PureComponent {
    state = {
        tracksViewChanges: true,
    }
    componentWillReceiveProps(nextProps) {
        if (!isEqual(this.props, nextProps)) {
            this.setState(() => ({
                tracksViewChanges: true,
            }))
        }
    }
    componentDidUpdate() {
        if (this.state.tracksViewChanges) {
            this.setState(() => ({
                tracksViewChanges: false,
            }))
        }
    }

    render() {
        return (
            <MapView.Marker
                tracksViewChanges={this.state.tracksViewChanges}
                {...this.props}
            >{this.props.children}</MapView.Marker>
        )
    }
}

MapMarker.defaultProps = {
    children: null,
};

MapMarker.propTypes = {
    children: PropTypes.any,
};

Then just use this MapMarker within your maps

Custom Marker is lagging very slow and its looks like CPU usage is growing steadily (i can feel the heat in phone). I tried with tracksViewChanges={false} once did update is done. But still can see lag, Zoom in/out are pretty hang and dead slow after using for a while.

I don’t know how I closed this but I think the issue still remains. This is just a patch that can be used until the underlying code is fixed

@Balasnest You can use the icon prop. I have no idea what youre trying with the key there but I know its wrong.

I have some custom markers defined as below:

import React, { useEffect, useRef, memo, useCallback } from 'react'
import { Animated } from 'react-native'
import { Marker } from 'react-native-maps'
import { Icon } from 'native-base'

const AnimatedIcon = Animated.createAnimatedComponent(Icon)
const scaleDuration = 200

export default memo(({ style, selected, ...markerProps }) => {
  const scale = useRef(new Animated.Value(1)).current

  const scaleTo = useCallback(
    value => {
      Animated.timing(scale, {
        toValue: value,
        duration: scaleDuration,
        useNativeDriver: true,
      }).start()
    },
    [scale]
  )

  useEffect(() => {
    scaleTo(selected ? 1.2 : 1)
  }, [scaleTo, selected])

  const transformStyle = { transform: [{ scale }] }

  return (
    <Marker.Animated
      {...markerProps}
      // don't track changes to increase perfs
      tracksViewChandges={false}
      tracksInfoWindowChanges={false}
    >
      <AnimatedIcon
        type="MaterialCommunityIcons"
        name="map-marker-circle"
        fontSize={30}
        style={[style, transformStyle]}
      />
    </Marker.Animated>
  )
})

And using index as the marker key seems improve perfs on android. It may be just a feeling, bit it seems too be the case.

Any idea why ? You seem to say it won’t improve perfs ?

This happens to me, too. Very critical issue.