mapbox-maps-ios icon indicating copy to clipboard operation
mapbox-maps-ios copied to clipboard

Location Consumer Taking Up too much Main Thread Space and Lagging Map

Open henryouang opened this issue 3 years ago • 2 comments

Environment

  • Xcode version: 13.4.1
  • iOS version:
  • Devices affected:
  • Maps SDK Version: 10.6.1

Observed behavior and steps to reproduce

Do a few calculations that must be on the main thread as you pan the map. The frame rate of the application drops significantly, even while idle.

Expected behavior

No frame rate lag, especially when map is idle.

Notes / preliminary analysis

I have some calculations I need to do on the main thread for manual clustering because that doesn't seem to be supported right now. The problem is, with all these calculations, the frame rates don't make the cut and the lag is non-production ready. Upon further investigation, I found this snippet of code that took up much of my main thread queue in the location consumer in v10.6.1:

extension InterpolatedLocationProducer: LocationConsumer {
    internal func locationUpdate(newLocation: Location) {
        let currentDate = dateProvider.now

        // as a first iteration, assume a 1s location update interval and use a
        // slightly longer interpolation duration to avoid pauses between updates
        let duration: TimeInterval = 1.1

        if let location = interpolatedLocation(with: currentDate) {
            // calculate new start location via interpolation to current date
            startLocation = location
            startDate = currentDate
            endLocation = InterpolatedLocation(location: newLocation)
            endDate = currentDate + duration
        } else {
            // first location: initialize state, no interpolation will happen
            // until the next location update
            startLocation = InterpolatedLocation(location: newLocation)
            startDate = currentDate - duration
            endLocation = startLocation
            endDate = currentDate
        }
    }
}

Looking at my OS log, this function is called many many times within one second and clogging up my main queue. I don't think it is necessary to call it this many times in such a short period of time. This lag is even present when the map is idle. When looking at my CPU usage, there is a ton of activity even when I am not moving the map.

After commenting the above code out, my calculations make the cut and the frame rate is back to normal. I know this is essential to displaying the puck on the map, but can't we limit it rather than call it 10 times a second?

Please let me know what I should do. Thank you.

henryouang avatar Jul 28 '22 04:07 henryouang

Hi @enteleca, thanks for the detailed report! This method is invoked whenever CLLocationManager sends an updated location or heading. If these updates happen to frequently - try setting a distance filter with LocationOptions.distanceFilter.

evil159 avatar Aug 03 '22 13:08 evil159

Hi @enteleca, thanks for the detailed report! This method is invoked whenever CLLocationManager sends an updated location or heading. If these updates happen to frequently - try setting a distance filter with LocationOptions.distanceFilter.

Hi @evil159, thanks for the response. Upon investigation, I noticed that this was being called on the main queue. To experiment, I switched it over to a background thread and so far everything seems to be running smoothly with significantly improved frame rates. Perhaps we could move locationUpdate onto a background thread? What is a reason we couldn't just move it onto a background thread?

On the topic of the distance filter, that is a great idea, however I would like my location to be as accurate as possible in my situation. Throwing the call on background thread I have found is sufficient for my purposes.

henryouang avatar Aug 05 '22 06:08 henryouang