mapbox / mapbox/mapbox-maps-ios
CircleLayer animations consume the CPU
Nobody has claimed this yet.
- Dominant language
- Swift
- Stars
- 601
- Forks
- 196
- PR merge metrics
- No merged PRs in 30d
Description
## Environment
- Xcode version: 13.2.1
- iOS version: 15.3.1
- Devices affected: All
- Maps SDK Version: 10.3.0
Thank you for making such a wonderful SDK!
## Observed behavior and steps to reproduce
I'm implementing a style-driven pulse animation using a CircleLayer. The pulse is a colored circle border that grows from its center coordinate while simultaneously fading out. My goal is to avoid a UIView-backed annotation because I want the pulse to render underneath certain style layers within the map.
https://user-images.githubusercontent.com/1591735/157763500-dc724474-909b-4c69-91ff-46066c4f6282.mov
I have tried two approaches for this style layer animation:
1. Use the `circleRadiusTransition`, `circleStrokeWidthTransition`, and `circleStrokeOpacityTransition` properties to allow the MapView to automatically animate the corresponding `circleRadius`, `circleStroke` and `circleStrokeWidth` properties. [The Here is a Gist containing this transition approach.](https://gist.github.com/johnnewman/266f921682ce799aed24765e04a10a04)
2. Manually update the `circleRadius`, `circleStroke` and `circleStrokeWidth` 60 times a second on the main queue. [Here is the Gist with the manual/rapid updates.](https://gist.github.com/johnnewman/b2b76aae3cde66b1e3a0d77555647b93)
In either approach, on an iPhone 12 Pro with iOS 15.3.1, the Xcode debugger reports my CPU utilization around 40% while the pulse animation is running. This consumes a lot of energy and slows down the app. Similarly, either approach on an iPad mini 4 with iOS 15 utilizes 100% of the CPU.
## Expected behavior
Animating a CircleLayer via the provided transition properties should be relatively performant. When using the transition properties, CPU utilization under 20% on a recent iOS device, like an iPhone 12, would be ideal.
## Notes / preliminary analysis
I have also implemented this same animation using a UIView-based annotation with Core Animation. This approach is much more performant and utilizes around 3 to 7% CPU. Knowing that, my goal is to still run the animation nested in the stack of style layers so that I have better Z-level control.
## Additional links and references
- [Gist using transition properties](https://gist.github.com/johnnewman/266f921682ce799aed24765e04a10a04)
- [Gist rapidly updating circle properties in a loop](https://gist.github.com/johnnewman/b2b76aae3cde66b1e3a0d77555647b93)
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start by reproducing the CircleLayer animation with the transition-property and rapid-update approaches shown in the linked Gists on the listed iOS devices. Profile CPU usage while the pulse runs and compare it with the UIView/Core Animation baseline. Done means identifying and addressing the performance issue so CircleLayer animation approaches the reported under-20% CPU target on a recent device.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- ios, swift
- Domain
- mobile-dev, performance
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 48/100