Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to stop GMSMapView renderer?

I noticed a performance issue when using GMSMapView as part of my view hierarchy. Important note: the map doesn't take up the whole screen, it is used as a table view header. These issues affect the behaviour of the table view itself - low FPS, which results in a bad user experience, so I'm trying to resolve these issues or at least understand what GMSMapView is doing.

Using Time Profiler I found out that this is cased by the GMSMapView re-rendering on every frame (as I can tell), because the heaviest stack trace on the main thread is:

enter image description here

Which is called from: CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE1_PERFORM_FUNCTION

(I guess it's just how internals of Google Maps work - it registers a CADisplayLink with a runloop and re-renders it on each frame)

This results in a heavy CPU usage (up to 99%):

enter image description here

Note that on the selected area nothing really happens to the app, it just displays a static map and a table view (no user interaction, no frame changes, no anything)

If I conduct the same test without a GMSMapView as a subview, the CPU usage in the same place is almost 0%:

enter image description here

Now to the question. Why is that happening and how to stop this behaviour?

I found a method called - (void) stopRendering on a GMSMapView, and tested it - the results are good and I get the same performance as when I completely remove the map view. However, this method is marked as deprecated and it states that it will be removed in a future releases of the SDK, which makes it a bad candidate for a long-term solution.

Any help, explanation or clues will be appreciated!

like image 670
markvasiv Avatar asked Nov 24 '18 16:11

markvasiv


1 Answers

The problem with stopRendering is that it places the burden of managing the map state on the developer.

Instead of using stopRendering, you should limit the frame rate of the object. GMSMapView has a property called preferredFrameRate. You should be using that. It says in the documentation that by default preferredFrameRate is set to maximum, or to re-render every frame.

preferredFrameRate is of an enum called GMSFrameRate. Which has values:

  1. kGMSFrameRatePowerSave
  2. kGMSFrameRateConservative
  3. kGMSFrameRateMaximum

You should be using #2 to ensure that the map stays fluid during user interaction, but also doesnt render needlessly. By default preferredFrameRate is set to #3.

like image 114
Dylan Avatar answered Oct 03 '22 18:10

Dylan