-
-
Notifications
You must be signed in to change notification settings - Fork 348
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
Text rendering or collision detection performance issues #3223
Comments
I'm not sure if #2382 could resolve at least part of the problem but it sounds relevant. |
Hi @Buthrakaur thanks for sharing your performance-related issue! Looping in @sjg-wdw. Maybe the rendering team can have a look at it. Do you have the style available as a JSON? Would you be willing to (privately) share your style with MapLibre developers? We're always interested in heavy styles to help improve performance. We have some tracing integrated which can be helpful to study what in particular is slowing things down. |
Could this be a problem with sorting? @TimSylvester |
I wouldn't think so, but it doesn't seem like layout or rendering should be significant in that case. |
Hi @louwers, we would really appreciate that your rendering team could take a look at it. how should I get the style as JSON?? I have just this: `pinSmallStyle: {"iconImage":["get","small"],"iconColor":["get","iconColor"],"symbolSortKey":["get","priority"],"iconAnchor":"center","iconSize":0.5} pinMediumStyle: {"textHaloWidth":2,"textHaloBlur":0,"textAnchor":"top","textMaxWidth":10,"textFont":["get","textFont"],"iconAllowOverlap":false,"textAllowOverlap":false,"iconOptional":false,"iconAnchor":["get","iconAnchor"],"symbolSortKey":["get","priority"],"textOffset":[0,0.1],"textField":["get","title"],"iconImage":["get","medium"],"textSize":["case",["==",["get","type"],"tour"],14,12],"textColor":["get","textColor"],"iconColor":["get","iconColor"],"textHaloColor":["get","textHaloColor"],"iconSize":0.5} pinLargeStyle: {"textHaloWidth":2,"textHaloBlur":0,"textAnchor":"top","textMaxWidth":10,"textFont":["get","textFont"],"iconAllowOverlap":false,"textAllowOverlap":false,"iconOptional":false,"iconAnchor":["get","iconAnchor"],"symbolSortKey":["get","priority"],"textOffset":[0,0.1],"textField":["get","title"],"textSize":14,"textColor":["get","textColor"],"textHaloColor":["get","textHaloColor"],"iconImage":["get","large"],"iconSize":0.5}` THX! |
@jakub-oone We would need the sources as well in order to debug it. You could use https://maplibre.org/maputnik to create it. |
@louwers you mean ShapeSource with shapes? Like this? of course there are much more features... |
We were finally able to isolate the issue and prepared a minimum sample repo here: https://github.com/SmartGuideApp/maplibre-test - it's a React Native app so for running it on iOS following sequence needs to be done:
The root cause of the performance problem is style having |
Sort keys are very slow. Do you need them here? |
We are going to stop using them of course as we can sort the features array instead but I believe it would still be great if the performance get fixed at some point of time or at least include a warning in the docs or make this style property obsolete. Mapbox component handles this without any issues - they probably implemented some optimization after the fork was made. |
It's expected to be slower because things that can normally be grouped together can't be when sorted, but there may still be some problem making it slower than it should be. From just the screenshot above, it doesn't seem like there are enough instances that it should be noticeable. |
I wonder if there are a lot of symbols not appearing. |
yes - there's over thousand symbols with 3 layers (small/medium/large icons) |
This is starting to make more sense. Icon and text deconfliction is done in real time in the renderer. It's a legacy of the original design and it works well if most of the things you give it are going to appear on the screen. At a certain point, when most of the things you give that deconfliction engine are invisible, you're using it wrong. It's only meant to make a few very quick decisions. MapLibre could help fix this by moving deconfliction out of the main rendering loop so it could take as long as it needs. Working through 1k or even 100k items isn't all that bad if you do it right, just not at 30fps. We did this in WhirlyGlobe and it was just a matter of memory. But for the short term, you can avoid sorting or just feed it fewer things to deconflict. |
I could be wrong, but I don't think sorting directly affects the placement pass. I'd expect it to only apply to things that end up being selected for rendering. Possibly we're sorting the entire list of things and only rendering some, but the sort itself should be cheap, even for thousands of items, it's creating drawables and rendering them that seems most likely to be a problem. |
@TimSylvester I would expect exactly what you are saying (sorting array of ~thousand items being cheap operation => no perceivable effect of using I recorded a screen recording from our real app if you want to see the difference - I was quickly zooming in and out. This is app version without |
The actual sort is very cheap, it's actually an ordered insert into a list based on a float key. The other odd part is it being worse on iOS. If that's not a red herring, it implies it h as something to do with rendering itself, pretty much everything else is platform-neutral. Are you able to get a Metal frame capture with profiling? |
@TimSylvester I'm not fluent in iOS native development so that would be hard for me honestly but if it's easy for you the sample repository #3223 (comment) has exactly the same perf issue - would that be possible, please? |
@Buthrakaur Could you try these steps? https://developer.apple.com/documentation/xcode/capturing-a-metal-workload-in-xcode |
|
@TimSylvester thanks for giving it a try. I use Mac only seldomly so I'm not sure what can be wrong with CocoaPods on your computer but there's some docs here: https://reactnative.dev/docs/set-up-your-environment?os=macos&platform=ios#cocoapods or here: https://guides.cocoapods.org/using/getting-started.html |
I can see in the manual |
|
@TimSylvester |
I mean that after running Now I get |
We just migrated from Mapbox to Maplibre and discovered degraded performance especially on iOS (React Native app for both platforms) when zooming in/out or quickly panning the map. We have 3 symbol layers with small/medium/large variants of POI markers to let collision use the largest possible icon available for a nice map UX with hundreds of POIs in a city. I discovered the rendering performance goes massively down when I add a text in the style and especially when I set text halo (
textHaloWidth
,textHaloColor
) so I had to turn off text halo effects to keep at least some acceptable performance. The Mapbox component seems to have some more performance optimization around text collision detection or text rendering in general. It's surprising the Android performance is still acceptable (even though worse than Mapbox) and it's sluggish on iPhones.I'd appreciate any recommendations on how to improve the performance by changing the style - I ended up with this:
This is the intended result which worked well with Mapbox in terms of performance but is not acceptable with MapLibre on iOS:
The text was updated successfully, but these errors were encountered: