flutter-vector-map-tiles icon indicating copy to clipboard operation
flutter-vector-map-tiles copied to clipboard

Performance issues

Open giaur500 opened this issue 2 years ago • 104 comments

I noticed performance when zooming/moving is actually poor in compare to native solutions like Google Maps or Mapbox official api. On low end devices map is almost unusable.

From other side, raster tiles from flutter map plugin are still very fast. Are you aware performance issues and is there anything possible to make it working faster?

giaur500 avatar Feb 15 '23 08:02 giaur500

If you are interested, there are some past conversations in the closed issues where you can have a read and might add some ideas. The tile rendering (drawing on canvas) is currently only possible in the flutter main isolate (https://github.com/flutter/flutter/issues/75755), when I'm not mistaken this is still the bottleneck.

You can improve performance by tuning your style. Feel free to do your own experiments and share it with us :)

FaFre avatar Feb 15 '23 09:02 FaFre

We've done a lot of work to address performance issues, but it's still not as good as raster or native maps. Poor performance is most noticeable with tiles having a lot of data (e.g. in LA or London). You can find previous discussions by searching for other issues

The theme can make a big difference as noted by @FaFre (thanks!) but you may find that raster tiles are needed to get the performance that you want, depending on your use-case.

I've added some examples that you may find helpful here: https://github.com/greensopinion/flutter-vector-map-tiles-examples There are two custom themes in there that may help with performance.

greensopinion avatar Feb 16 '23 04:02 greensopinion

As far as I understand, currently is not possible to optimize it becuse of Flutter limitations? Ok, I will try themes, Indeed, a lot of data causes poor performance.

giaur500 avatar Feb 16 '23 09:02 giaur500

@greensopinion I pushed the flutter issue and got a response that flutter_isolate plugin might improve performance and gain access to dart ui: https://github.com/flutter/flutter/issues/75755#issuecomment-1434935593

However, this plugin is only Android/iOS compatible, do you see any chance this would improve the current performance?

FaFre avatar Feb 17 '23 17:02 FaFre

Yes, there's a good chance that it could be used to offload some CPU-intensive tasks off the UI thread. We are already offloading some work to isolates, but there are many things that can't be offloaded due to use of dart:ui.

I imagine that the easiest and most beneficial thing to do would be to render a raster image on an isolate. This could either be integrated directly with the existing flutter_map raster tile capabilities, or perhaps in vector_map_tiles. The idea would be to render vector tiles as images and supply those to flutter_map. The benefit over using raster tiles directly would be choice of themes client-side, and rendering tiles at higher zoom levels that aren't normally available. At 2x (retina) size raster tiles look pretty sharp, but we could even render tiles at incremental zoom levels (e.g. a tile at 14.25 zoom instead of 14 then scaled to 14.25)

I'm a little reluctant to invest in functionality that is using officially unsupported flutter/dart capabilities, such as dart:ui on non-UI isolates. As noted on flutter/issues/75755 things may already break with Impeller.

If we consider moving forward with this idea, we should first evaluate how Impeller affects performance. For example, a comparison running the example library in the profiler with Impeller and without would be really helpful.

greensopinion avatar Feb 18 '23 17:02 greensopinion

@greensopinion do you think it's possible to disable Impeller and use isolates on Android only?

giaur500 avatar Feb 19 '23 10:02 giaur500

At least for now it's possible - but that will likely change once Flutter fully adopts Impeller since they won't want to maintain two separate rendering frameworks for Android indefinitely.

greensopinion avatar Feb 19 '23 16:02 greensopinion

I don't know how much work is it, but I think better to use isolates on Android, even as temporary solution. Still more than nothing.

giaur500 avatar Feb 19 '23 18:02 giaur500

However, this plugin is only Android/iOS compatible, do you see any chance this would improve the current performance?

I've pushed an experiment to https://github.com/greensopinion/flutter-vector-map-tiles-raster-experiment Feel free to try it out!

greensopinion avatar Feb 22 '23 16:02 greensopinion

It works pretty fast, almost the same performance as native Google Maps. Very good result in my opinion. Not tried on iOS though

giaur500 avatar Feb 24 '23 10:02 giaur500

Hey I just tried out that experiment on iOS and the performance is really good!

aamirki avatar Mar 08 '23 18:03 aamirki

After more testing. It seems to be better, but still not as good as rester map or native maps like Google Maps. I will test without any style applied to see how does it work, possible only style applied causes better performance

giaur500 avatar Mar 09 '23 07:03 giaur500

I've created a branch in this repository for experimentation: flutter-vector-map-tiles/tree/raster-experiment

There are a few things needed to take it further:

  1. there may be a memory leak
  2. the API is unnatural and needs revisiting
  3. there is no way to plug in rendering in a separate isolate
  4. tuning

greensopinion avatar Mar 19 '23 23:03 greensopinion

However, this plugin is only Android/iOS compatible, do you see any chance this would improve the current performance?

I've pushed an experiment to https://github.com/greensopinion/flutter-vector-map-tiles-raster-experiment Feel free to try it out!

It works really cool. But there is some problem in my case. When I'm panning for a long distance it seems that a huge number of isolates creates for all panned tiles. Seems like tile provider doesn't drop deprecated isolates for tiles which was rapidly panned. For example, I have 100 tiles on the map and I`m trying to pan from 1 tile to 99 tile by one swipe. Tile provider starts to create 99 isolates and tries to process them all but not just skips unnecessary tiles and process only several last tiles.

Pepslee avatar Mar 26 '23 13:03 Pepslee

The experiment is only intended as a proof-of-concept. There is a lot of work needed to make it ready for real usage.

I've been working on #129 to introduce raster images as an alternative to vectors. Raster images have the advantage of improved frame rate (less jank) and they only need to be rendered the first time since they can be stored in the cache for future use. The result is quite good. Of course, raster images aren't as sharp at fractional zoom levels. #129 is now available as version 3.3.0 of this library.

greensopinion avatar Mar 26 '23 22:03 greensopinion

The experiment is only intended as a proof-of-concept. There is a lot of work needed to make it ready for real usage.

I've been working on #129 to introduce raster images as an alternative to vectors. Raster images have the advantage of improved frame rate (less jank) and they only need to be rendered the first time since they can be stored in the cache for future use. The result is quite good. Of course, raster images aren't as sharp at fractional zoom levels. #129 is now available as version 3.3.0 of this library.

Thank you, I have already tried this update, it work really faster, but I still have freezes ((. In any case any calculation in main thread entail freezes of the UI. Even if they won't be visible for the human eye, but they will still affect any timer or animation in app. I hope this problem will be solved with impeller, and there will be a mechanism for rendering in non main thread.

Pepslee avatar Mar 27 '23 07:03 Pepslee

@greensopinion Please note https://pub.dev/packages/flutter_map/versions/4.0.0-dev.1/changelog

JaffaKetchup avatar Apr 04 '23 12:04 JaffaKetchup

Thanks Luke. Is the update to let me know about API changes or does it specifically relate to performance?

On Tue, Apr 4, 2023 at 5:15 AM Luka S @.***> wrote:

@greensopinion https://github.com/greensopinion Please note https://pub.dev/packages/flutter_map/versions/4.0.0-dev.1/changelog

— Reply to this email directly, view it on GitHub https://github.com/greensopinion/flutter-vector-map-tiles/issues/120#issuecomment-1495869846, or unsubscribe https://github.com/notifications/unsubscribe-auth/AEKDQ7WZYRQ3S72XYZHLMNDW7QGGPANCNFSM6AAAAAAU4Q2O2E . You are receiving this because you were mentioned.Message ID: @.***>

greensopinion avatar Apr 05 '23 04:04 greensopinion

@greensopinion Both. Probably not a massive performance improvement, but there is a chance it will help. There are major API changes - but I'm not sure if any of them will affect you. Probably the most major for plugin maintainers is the renaming of Coords to TileCoordinates.

JaffaKetchup avatar Apr 05 '23 12:04 JaffaKetchup

Thanks @JaffaKetchup - created #136 in preparation for flutter_map major version change.

greensopinion avatar Apr 05 '23 15:04 greensopinion

Hey @greensopinion, was trying to follow up on your discussion here about using flutter_isolate to offload processing yet still able to call dart.ui functions outside the main isolate. It's not the full solution I understand from your comment here, but part of it. The other part being the complexity of the theme, which you're trying to solve by selectively delaying the rendering if I understood correctly.

I'm not sure I got it right, but per nmfisher's (flutter_isolate maintainer) last comment here, the status on this PR being merged into dart's main branch and the comment here, it appears that the functionality that Impeller previously blocked on iOS should now be back again with Dart 3?

Does this mean, flutter_isolate + selective delays COULD solve many of our performance issues? What am I missing?

mdmm13 avatar Oct 03 '23 12:10 mdmm13

Hey, @greensopinion - have you considered drawVerticesRaw for rendering? It seems to be orders of magnitude faster than using widgets or canvas. This video explains it very thoroughly and the bookmarked section shows a comparison between the different methods; https://youtu.be/pD38Yyz7N2E?t=742

DavidDohmen avatar Oct 30 '23 12:10 DavidDohmen

Hey, @greensopinion - have you considered drawVerticesRaw for rendering? It seems to be orders of magnitude faster than using widgets or canvas. This video explains it very thoroughly and the bookmarked section shows a comparison between the different methods; https://youtu.be/pD38Yyz7N2E?t=742

Would probably solve all problems with vector maps without going GL?

mdmm13 avatar Oct 30 '23 18:10 mdmm13

Just for context, we're looking into potentially using drawVertices to draw polygons in FM, but that's still in mostly private discussion. You may also be interested in dart_earcut (self-promo :D), which will perform the triangulation needed for drawVertices extremely quickly (it doesn't work well on self-intersecting polys, they'll need to be simplified into multiple simple polys).

JaffaKetchup avatar Oct 30 '23 20:10 JaffaKetchup

Looks promising! Feel free to prototype something.

greensopinion avatar Oct 31 '23 00:10 greensopinion

Unfortunately I have neither the time nor skillset to do so. We would however contribute financially with a bounty, if a certain speed level is reached, because then flutter_map would become feasible as an alternative to mapbox for us. So if anyone with the right skillset wants to pick this up, let's talk!

DavidDohmen avatar Oct 31 '23 12:10 DavidDohmen

I might be able to spend some time on this in the near to medium term. So I was wondering, first of all, whether somebody is already working on this or on similar things with drawVertices in FM as @JaffaKetchup mentioned?

j-bbr avatar Dec 12 '23 13:12 j-bbr

@j-bbr Right now we are not implementing drawVertices, and if we do, it'll be for Polygons only: we have no plans to make a vector layer for now.

JaffaKetchup avatar Dec 12 '23 18:12 JaffaKetchup

Go for it!

On Tue, Dec 12, 2023 at 5:56 AM j-bbr @.***> wrote:

I might be able to spend some time on this in the near to medium term. So I was wondering, first of all, whether somebody is already working on this or on similar things with drawVertices in FM as @JaffaKetchup https://github.com/JaffaKetchup mentioned?

— Reply to this email directly, view it on GitHub https://github.com/greensopinion/flutter-vector-map-tiles/issues/120#issuecomment-1852086285, or unsubscribe https://github.com/notifications/unsubscribe-auth/AEKDQ7X4E6PH7CN5XGCBW7LYJBPARAVCNFSM6AAAAAAU4Q2O2GVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMYTQNJSGA4DMMRYGU . You are receiving this because you were mentioned.Message ID: @.***>

greensopinion avatar Dec 13 '23 14:12 greensopinion

@greensopinion Just to keep an open mind for which improvements to go for I was wondering whether I could get your opinion on the following so I don't go down a path that has already turned out to be a dead-end for you: Besides drawing faster, potentially with drawVertices there is of course also the option to draw slower :) meaning in this case to spread drawing out over multiple frames. You're of course already doing that with Text but maybe this could be extended to partial drawing of layers (at the moment all layers except symbols are drawn in one frame, please correct if I am wrong here)?

Rough Todo-List: keeping track of partially drawn tiles partially drawing layers (fixed number initially, maybe within a time budget later) retaining the partially drawn state efficiently for continuation in the next frame (not possible afaik with CustomPainter, maybe the VectorTileLayerMode.raster code can be a start for this, or triangle lists for drawVertices)

Any thoughts, pitfalls you can already see here?

j-bbr avatar Dec 14 '23 09:12 j-bbr