Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Performance tips for many markers #369

Closed
allthetime opened this issue Jul 9, 2016 · 21 comments
Closed

Performance tips for many markers #369

allthetime opened this issue Jul 9, 2016 · 21 comments

Comments

@allthetime
Copy link
Contributor

Hi, I have about 300 markers on a map.

First of all, it loads incredibly slow (5-10 seconds?)

And secondly, it crashes frequently when zooming around for a while and going back and forth between the map view and another view.

I was using custom views for markers, but I stopped because performance was much worse.

Does anyone have any tips on dealing with this? Or a way I could have batches of markers load synchronously to lower the strain on the initial load?

@jeveloper
Copy link

I'd suggest doing this

handle region change , means mapview region=..... not initialRegion
implement OnRegion

as you change , redraw a limited amount of markers , keep your array at say 20 markers.
You can deduce how far the person has moved from lat/lng and redraw on say each 5km difference.

Ideally it would be great to know exact 4 points of the viewable map and use that as your geo fence.

hope that helps

@zelll
Copy link

zelll commented Jul 12, 2016

and

  1. select right key for markers.
  2. try implementing shouldComponentUpdate() on your marker class.

@danvass
Copy link

danvass commented Jul 23, 2016

I'm similarly looking at ways to optimise the loading and usage of many markers with custom images, any other tips appreciated.

@saadibrahim
Copy link

Look into clustering of markets.. combine nearby markers into one.. expand on zoom

@arondeparon
Copy link

@allthetime would love to hear if you have solved this issue and, if so, how you did it. I'm working with a similar number of markers and need to solve this same problem.

@zvoncha
Copy link

zvoncha commented Jan 3, 2017

I had similar problem with 300+ markers. However, in my app, I did not have problems with maps per se, but with other parts of the app. For the example, drawer component (third party) was really slow and it took about 5-10sec for drawer to opens, also closing drawer animation was really bad (in a case if current zoom out level is low and all 300+ locations are visible in view/map). In our case that was bottleneck of speed and performance.

So I did a simple trick to solve the issue (it is specific to my app, but it may help others).

On events (like pressing the button that opens drawer or some other view) I used methods to achive this functionalty:

  1. User press some button -> App hides all location -> Something happens (new view is opened or drawers is opened)
  2. In a case of closing drawer - when animation ends and specific timeout is passed (100ms) locations are again visible (I added timeout because of smooth animation that are specific for drawer component)

Like I said, in my case that works perfectly. Because I don't need to show locations if something else is going to be visible in view.

I made a little app screen recording video (it has glitch when closing drawer but its only visible when recording, in non recorded app it doesnt exist)

https://www.youtube.com/watch?v=iTo6i2romA8

@iwoork
Copy link

iwoork commented Mar 6, 2017

Any code sample to show how this is implemented?

@danvass
Copy link

danvass commented Mar 6, 2017

Unfortunately my issue was that the map itself was laggy, although this solution may reduce lag when doing something other than the map it won't stop the map itself from being laggy.

I attempted at using Supercluster to only display what's on screen and cluster markers if too many are on screen - however there was a noticeable delay each time the region changes on the screen and require the clusters to be calculated and rendered again.

@thomasbaldwin
Copy link

Any solution for this? I'm noticing react-native-maps is extremely slow and uses at least 200MB of memory by itself. Seems a little excessive

@oskaryil
Copy link

oskaryil commented Aug 8, 2017

@dvassilev I tried the same thing using supercluster but found that there was quite noticeable delays as well. Tried this with about ~5000 markers

@6ewis
Copy link

6ewis commented Aug 21, 2017

@oskaryil how did you solve the delay with supercluster.

@oskaryil
Copy link

@6ewis I didn't. I'm not using it atm and instead just waiting for a solution to be added to this package.

@davidhellsing
Copy link

davidhellsing commented Oct 30, 2017

I solved it by:

  1. Maunally applying the patch in this commit: 0ab321b

  2. Saving the patch using https://www.npmjs.com/package/patch-package

  3. Creating another MapMarker component that toggles the tracksViewChanges property when receiving props, something like:

// @flow

import React, { PureComponent } from 'react'
import MapView from 'react-native-maps'
import isEqual from 'lodash.isequal'

type Props = {
  children: React.Node,
};

type State = {
  tracksViewChanges: boolean,
};

export default class MapMarker extends PureComponent<Props, State> {
  state = {
    tracksViewChanges: true,
  }
  componentWillReceiveProps(nextProps: any) {
    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>
    )
  }
}

@markmssd
Copy link

@alvelig I think this issue was resolved with this merged PR #1705. Looks like it's the same thing

@alvelig
Copy link
Contributor

alvelig commented Dec 15, 2017

Yep, in my case the image I used for the marker was too large, and some re-rendering issues. If someone has performance problems feel free to open a new issue (according to the new template and we will help)

@alvelig alvelig closed this as completed Dec 15, 2017
@bduyng
Copy link

bduyng commented Jan 26, 2018

@alvelig same problem with marker images, they were too large. Did you find a solution yet?

@alvelig
Copy link
Contributor

alvelig commented Jan 26, 2018

@bduyng see #725

@victormartingarcia
Copy link
Contributor

victormartingarcia commented Jan 5, 2019

I solved it by:

  1. Maunally applying the patch in this commit: 0ab321b
  2. Saving the patch using https://www.npmjs.com/package/patch-package
  3. Creating another MapMarker component that toggles the tracksViewChanges property when receiving props, something like:
// @flow

import React, { PureComponent } from 'react'
import MapView from 'react-native-maps'
import isEqual from 'lodash.isequal'

type Props = {
  children: React.Node,
};

type State = {
  tracksViewChanges: boolean,
};

export default class MapMarker extends PureComponent<Props, State> {
  state = {
    tracksViewChanges: true,
  }
  componentWillReceiveProps(nextProps: any) {
    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>
    )
  }
}

@davidhellsing this works great, but I am experiencing a small glitch.

We currently retrieve in-boundary markers from the database on event onRegionChangeComplete callback, but sometimes the markers disappear. The thing is they ARE loaded on Map component, because when you start dragging they appear back.

It must be something related to the tracksViewChanges property:

tracksviewchanges

Any ideas on how to prevent that?

@piashcse
Copy link

piashcse commented Jun 12, 2019

@davidhellsing thank you bro for such a nice solution. This issue made me suffer a lot. But if I load more marker by pagination.it will again slow down. In that case I make tracksViewChanges again false and its working fine now 😊.

import React, {PureComponent} from 'react'
import MapView from 'react-native-maps'
import isEqual from 'lodash.isequal'

export default class MapMarker extends PureComponent<Props, State> {
    state = {
        tracksViewChanges: true
    }

    componentWillReceiveProps(nextProps: any) {
        if (!isEqual(this.props, nextProps)) {
            this.setState({
                tracksViewChanges: true,
            }, () => {
                this.setState({tracksViewChanges: false})
            })
        }
    }

    componentDidUpdate() {
        if (this.state.tracksViewChanges) {
            this.setState({
                tracksViewChanges: false,
            })
        }
    }

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

@mohmdalfaha
Copy link

Wrapping your marker with so many 's will drastically drop the UI performance. Thought of sharing this in case someone faces the issue in the future.

@Akshh057
Copy link

Akshh057 commented Dec 2, 2021

Try to use icon prop for custom marker image and tracksViewChanges={false} prop, this will surely increase the performance.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests