-
Notifications
You must be signed in to change notification settings - Fork 69
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
Performance issues #10
Comments
Hi, thanks for the kudos! Performance is a real problem when it comes to vector tiles. So great to hear that you're interested in contributing. There are a few things that you can do to tune the codebase as-is:
I've done the above and come up with a decent frame rate while zooming/panning. There is some jitter (i.e. skipped frames) especially in dense regions (e.g. London, UK) however the user experience is still pretty good. At one point I did experience freezing as you mentioned. I made some changes to the codebase to avoid rendering outside of the tile area for labels on the Canvas, and that made a huge difference. There's potentially more that could be done here (e.g. with polygons/lines) I wonder if your tiles contain shapes outside of the tile rendering area? That could be a good place to start with a contribution. The Flutter memory view is really helpful to see if you're hitting an upper memory limit. |
I've done some more work in this area since I was noticing jank on iPad. It's still not perfect, but these two commits make a big difference: Also, I've found that tuning the map style to reduce detail at different zoom levels can help. For example, the style that I'm using has minzoom=14 for road_minor, and minzoom=15 for road_minor_casing. By having casing for minor roads only render at zoom level 15 and above, there's half as much work to do at zoom level < 15. |
Cool, I will try it out. I should get to experiment with it more during the upcoming week |
Sure, here's a good place to start:
https://github.com/greensopinion/flutter-vector-map-tiles/blob/main/lib/src/options.dart#L39-L50
…On Wed, Oct 6, 2021 at 9:11 AM Emil ***@***.***> wrote:
Can you please give a hint on how to configure the file based caching?
Thanks!
—
You are receiving this because you commented.
Reply to this email directly, view it on GitHub
<#10 (comment)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/AEKDQ7VXTRY5UQJ2XFWK5Z3UFRYMTANCNFSM5B6ASJDA>
.
Triage notifications on the go with GitHub Mobile for iOS
<https://apps.apple.com/app/apple-store/id1477376905?ct=notification-email&mt=8&pt=524675>
or Android
<https://play.google.com/store/apps/details?id=com.github.android&referrer=utm_campaign%3Dnotification-email%26utm_medium%3Demail%26utm_source%3Dgithub>.
|
Hi. |
to do that you'll need to edit the map style, which you could do with a text editor but it's easier with something like https://maputnik.github.io The fewer things showing on a map, the less computationally expensive it is (i.e. the faster it will render.) There are a few ways to achieve fewer things while still having beautiful maps:
I hope that helps. If it's still not enough, you could use raster rendering which will provide the styling advantages of vector tiles, but without the crisp edges. |
thanks.i have one more question! maputnik gave me a JSON file and where do i use it? the map controller didn't have any styling property (like google map controller ) . |
@HusseinCopol You'd use that in your dart code like this: const _themeData = /* { all of this is your json } */;
final mapTheme = ThemeReader().read(_themeData); // You can also supply logger: Logger.console() to the ThemeReader to spot parsing issues with your theme. Then in your
|
I've found that most of the time spent rendering is looping over the theme layers so to increase performance, you can start by throwing out all layers from your theme, that you won't need. For example I built an app with a map scoped in Germany but the default theme from Mapbox includes a theme layer for US highway symbols. After trimming down the layers from a few hundred to just over a dozen which suffice in my case, performance went from 5 FPS went around 50 when zooming, moving and rotating. Of course if you have layers that should only show at specific zoom levels, using the minzoom/maxzoom properties works as well. |
I read the rendering code today, it was really a pleasure. Great work @greensopinion ! I was also doing some canvas painting, but on top of the standard flutter_map tile layer. In my case I had a big performance improvement when actually adding lines via When interested, take a look here: FaFre/dart-vector-tile-renderer@f43fffe But I think having 1-4 long running isolates and distribute the tile rendering jobs to them will bring a huge performance improvement. Downside, isolates are not supported for web. |
Thanks @FaFre, great to hear.
Feel free to issue a pull request - this is worth adding regardless of performance since it simplifies the code.
What do you have in mind for rendering jobs? From what I understand, calls to Canvas can only be done on the UI thread. |
regarding canvas on UI thread, there is a Flutter issue for this FYI |
Ohh too bad. I thought through the rasterization it could be also done in an isolate, but it seems like that it's not even possible to instantiate a |
@FaFre I couldn't wait - with some profiling I made a few changes inspired by your suggestion greensopinion/dart-vector-tile-renderer@548c0cc |
I've had a run at some performance related changes. There's more work to do, but there are some noticeable improvements in the latest release.
|
The latest release has more performance improvements. Some performance issues remain, clearly showing up as jank with the default theme. Current recommendations:
|
Closing based on recent optimizations including issues #21. Feel free to open a new issue if there continues to be a problem. |
A lot of work has been done to improve performance. There is still room for more improvement, however in testing I've found that |
I'm just adding a few bits here, after recent thoughts on the removal of raster discussion...some has already been covered I think, so apologies, just getting it out of my head before it pops out again. Some may have already been done! But writing it down in case someone wants to explore (I don't think I've got quite time to dabble atm, but will if I do). Generally in Flutter, canvas paths are typically very slow to render with strokewidths sub 1px (especially when zoomed) as it uses a different algorithm for linecaps etc. Sometimes there may be a path say at 1.2px...when pinchzooming, could anything between 1-2px be rendered at 0.99px for example (I experimented a bit with this in the renderer, and maybe it helped a little, in some cases, but not sure how the renderer would know if pinchzooming, or if thats better done outside the rendering code and figured before any calls to it) Generally calls to drawPath should be minimised. Can paths with the same style be grouped into one superpath (with a Move inbetween them), cache that path and draw (may be fiddly if using expressions that change per zoom, but could be done in inbeween zoom level changes). This may be similar to the addPolygon idea, but we can also group multiple lines as well. TextLayouts are typically expensive, so can that be cached (I know thats been discussed a bit before, not sure where that is currently), I was thinking about a simple storage of a previous frame type cache even. If a labels textlayout (based on latlng point and name for example) was stored in a hash of previous display frame/update, it should be able to be reused (I think!). I played with the idea of "overZooming" (I think there's another term for it, but it eludes me). So let's say we are at zoom 14. We draw the tiles at zoom 13, which means you only need a quarter of the tiles (some loss of lines maybe, but for tiles that have too much data it can help a bit). (Does this also play into the mapbox tilesize of 512 vs 256, not sure ?) Instead of drawPath, during a pinchzoom, can Canvas drawPoints with a PointMode of lines/polygon be used ? It may not need to calculate linecaps etc do maybe faster (similar to earlier...if a strokeWidth is < 4 say, do we care about accuracy of joins ? Now, I did try this a year or two ago, and the odd time got an out of mem error, but I think this was referencing GPU memory for point storage, and it may well be all of that is fixed now. If pinchzooming, could rendering be interrupted if a new zoom level comes in (bit fiddly this one...one may end up with blank tiles, not sure I like this...) ? Out of interest, is there a way for the rendering code to know that a pinchzoom is taking place ? I couldn't quite tell from the code if that's possible or not... |
Thanks for the ideas Ian!
…On Tue, Feb 22, 2022 at 1:44 AM Ian ***@***.***> wrote:
I'm just adding a few bits here, after recent thoughts on the removal of
raster discussion...some has already been covered I think, so apologies,
just getting it out of my head before it pops out again. Some may have
already been done! But writing it down in case someone wants to explore (I
don't think I've got quite time to dabble atm, but will if I do).
Generally in Flutter, canvas paths are typically very slow to render with
strokewidths sub 1px (especially when zoomed) as it uses a different
algorithm for linecaps etc. Sometimes there may be a path say at
1.2px...when pinchzooming, could anything between 1-2px be rendered at
0.99px for example (I experimented a bit with this in the renderer, and
maybe it helped a little, in some cases, but not sure how the renderer
would know if pinchzooming, or if thats better done outside the rendering
code and figured before any calls to it)
Generally calls to drawPath should be minimised. Can paths with the same
style be grouped into one superpath (with a Move inbetween them), cache
that path and draw (may be fiddly if using expressions that change per
zoom, but could be done in inbeween zoom level changes). This may be
similar to the addPolygon idea, but we can also group multiple lines as
well.
TextLayouts are typically expensive, so can that be cached (I know thats
been discussed a bit before, not sure where that is currently), I was
thinking about a simple storage of a previous frame type cache even. If a
labels textlayout (based on latlng point and name for example) was stored
in a hash of previous display frame/update, it should be able to be reused
(I think!).
I played with the idea of "overZooming" (I think there's another term for
it, but it eludes me). So let's say we are at zoom 14. We draw the tiles at
zoom 13, which means you only need a quarter of the tiles (some loss of
lines maybe, but for tiles that have too much data it can help a bit).
(Does this also play into the mapbox tilesize of 512 vs 256, not sure ?)
Instead of drawPath, during a pinchzoom, can Canvas drawPoints with a
PointMode of lines/polygon be used ? It may not need to calculate linecaps
etc do maybe faster (similar to earlier...if a strokeWidth is < 4 say, do
we care about accuracy of joins ? Now, I did try this a year or two ago,
and the odd time got an out of mem error, but I think this was referencing
GPU memory for point storage, and it may well be all of that is fixed now.
If pinchzooming, could rendering be interrupted if a new zoom level comes
in (bit fiddly this one...one may end up with blank tiles, not sure I like
this...) ?
Out of interest, is there a way for the rendering code to know that a
pinchzoom is taking place ? I couldn't quite tell from the code if that's
possible or not...
—
Reply to this email directly, view it on GitHub
<#10 (comment)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/AEKDQ7XQHLAMA5WLWDMFBWTU4NLIZANCNFSM5B6ASJDA>
.
Triage notifications on the go with GitHub Mobile for iOS
<https://apps.apple.com/app/apple-store/id1477376905?ct=notification-email&mt=8&pt=524675>
or Android
<https://play.google.com/store/apps/details?id=com.github.android&referrer=utm_campaign%3Dnotification-email%26utm_medium%3Demail%26utm_source%3Dgithub>.
You are receiving this because you modified the open/close state.Message
ID: ***@***.***
com>
|
Thinking out loud, I may be barking up the wrong street, so this may not apply! I was thinking about why I didn't really get any major text performance issues later on when experimenting with vector tiles. When I was doing Vector stuff, in the end, I ended up not using Positioned Widgets (maybe a hybrid is interesting..can't remember if I tried this). I suspect what may be happening is that every zoom change, all the text layouts need to be recalculated, and then readjusted inversely according to the scale (and text layout is very expensive iirc). However, in reality, we don't need to do any of this at all (unless we are either literally resizing the text to fit in with a road width for example, or curving text along a road). At all times, typically we want the text to be the same size (visually to the human eye). So we don't need to recalculate any of this, one can just reuse the old layout and draw on one none transformed Canvas. For example...all on one single upper Canvas
Apologies again, if this is a redherring. |
Where is this RenderMode being set? could not find it anywhere with latest version of the package |
With this implementation you have to make sure that chosen theme and map providers are same. In my case I have been using Stadia map provider and picked a theme from GeoApify. I started facing problems because of incompatibilities. Then I switched to GeoApify map provider with the following link inside
I have picked theme style from here
This has completed my implementation ... rest anyone can pick a theme from the plugin's gallery and can add to application by making sure both providers and theme are from same source. |
Hi there,
first kudos, its amazing someone finally took to implement native vector maps for Flutter,
unfortunately, I just tried this package with our own tiles and I am having serious performance issues, basically the map freezes and I am unable to interact with it, after every zoom change/movement, for a few seconds.
This happens both in debug mode (Android emulator/device) and release mode.
Our config: https://gist.github.com/filipproch/a010f95fcab7a559ab3074c3ebd0e290
We use the map mostly over Czech Republic - Europe
I would like to contribute to help improve this, but not sure where exactly to look/start
or maybe you already have some ideas for performance improvements?
The text was updated successfully, but these errors were encountered: