-
-
Notifications
You must be signed in to change notification settings - Fork 866
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
[BUG] TileLayer lag/jitter #1245
Comments
This comment was marked as off-topic.
This comment was marked as off-topic.
I don't get a problem on this for the Animated Controller example (in release or debug mode), is this on a very old device ? Are you using the latest from Git ? Try a, I'd be surprised if its related to slow calculations, there's only 3 markers there. |
Out of interest, I've created a webspace where I can publish the web stuff to, I'm going to try and have one for each version (happy to be added to the docs if wanted). Example.. https://fluttermap.dabbles.info/v0.15/#map_controller_animated (base at https://fluttermap.dabbles.info/v0.15/ ) For me, when I drag, I don't have a problem, however I do note if I click on Paris, then Dublin etc, it's almost as if the Markers move ahead and back as part of the animation (but again, doesn't if you drag them). |
I just updated the description to clarify that I slowed down the animation to 5 seconds as it makes the jitter more obvious. However even when it's not slowed down there is the weird affect where markers don't seem to move in sync with the map as you mentioned @ibrierley. I'm guessing the same root cause is responsible for the jitteriness as well as the markers seeming to move ahead and back again. To confirm I have no issues when dragging. Also I can confirm that I'm trying this on EDIT: I've just noticed that the glitch where markers move out of sync with the map occurs when flinging the map but not when dragging it. |
In that case, I'm likely wrong. Oops! |
I suspect this one will be quite tough to fix, so any inspiration welcome. If you add another layer in, like a polyline layer, I note that both that and the markers move in sync, but the tiles don't. So it "feels" like the tile layer is lagging behind, however the tile layer is a bit of an unweildly beast these days. |
Agreed. I'm going to keep digging.
That's a great point. I think this combined with the fact that the lagging/jittering doesn't seem to happen when dragging are the big clues. |
I've just been playing around with the tile layer code and I had a suspicion that its unusual way of listening to the movement stream and then calling setState when necessary was causing the lag. I have hacked up a local version which uses StreamBuilder like all of the other layers seem to do and I moved the In the following video I am using the usual tile layer and you can see the lag when flinging the map. Then I change to my modified version of AnimatedMapController which is using the hacked up tile layer with a StreamBuilder and there is no longer lag. fixed-tile-layer.mp4So the method of listening to the movement stream and then calling setState seems to be the cause of the problem. I can imagine that flutter performs the build caused by the setState call in the next frame (or something similar, I'm not extremely well versed in flutter's building/rendering semantics) which makes the tile layer lag. Even if I set the updateInterval to 0 the issue persists. I'm not very familiar with the TileLayer code but it seems to listen to the movement stream and only call setState when it deems necessary to avoid loading too many tiles (e.g. if you fling the map fast we wouldn't want to download/load all of the tiles you fling past). Perhaps we need to reconsider this pattern. The first thing that comes to mind is having a delay on the actual downloading/loading of the tile whilst not having that delay on the rebuilding of the displayed tiles. Does anyone else have other ideas on alternatives. Obviously we don't want to impact the performance of the TileLayer with this changes. |
Great digging! I suspected it was something like that, just hadn't had chance (or didn't want to :D), dig into the tile layer code. So I guess one question is, are there are any obvious negatives of using the typical Streambuilder method...why is the tile layer using a listen.... I'm a little confused about the fast map fling thingy though (I understand the concept of not wanting to download tiles passed through fast)...if the map is flung fast, and there's a stream listening...wouldn't it still have to reposition tiles, so I'm unsure how the method prevents tile loads....that's me probably not having dug through the code though ? Or is it more that the stream may mean it doesn't hitch so much or something ? |
Btw one thing we should probably do when testing any workarounds for this one, is test on some old slower devices. |
I've spent a lot of time in the last couple of days understanding/refactoring/fixing the TileLayer code and I seem to have solved the lag, my changes are in PR #1247. Let me know what you think @ibrierley. |
Hey, firstly great stuff! Thought things were quiet on this one, now I know why ;). I'll try and have a better dig at some point over the weekend as there's quite a bit changed, but just wanted to add a couple of thoughts on first test/glance. I think maybe there's a change in behaviour when there are none available tiles at the correct zoom level (but should be available tiles at a lower zoom that could be scaled). I'm guessing this is maybe around the toRemove() code, but I may be wrong. (although I can see the odd time it is scaled in certain cases) I.e are tiles now being removed from zoom 1 or 2 say, when we are on zoom 3 (but not loaded yet), as we're only testing for what we should draw now, not also what we could use as a "backup" tile. Best way to show this is on the animated MapController page. Click on London, in the original it will zoom in and use the old tiles scaled. In the new code, it's grey, and I think the previous behaviour is preferable (or at least as an option). The Levels stuff is interesting about precalculating, I had wondered if previous stuff was over optimization. I'd be interested if anyone else who knows that code better, knows if there is any specific reason for that, as I can't myself. What would be an extra bonus (as no one else bothers ;D, but it may be good to have when its fresh in peoples minds...), would be snippets of code documentation in a couple of areas, especially bits you found non-intuitive. I.e for me "what is a level, what is the purpose of updateLevels() type thing", , the word isn't clear and it's always bugged me :). Also what is "wrapping", there's crs wrapping and coord wrapping etc, and it's not always clear on glancing through code. |
Thanks for already having a look @ibrierley and nice spotting on the fact that the "backup" tiles are disappearing too soon. It's not immediately clear to my why this is the case. Interestingly I noticed that if I run in chrome with a throttled network connection (slow 3g, caching disabled) the behaviour is the same as before, the tile sticks around until the new one is loaded. If, however, I don't throttle the connection I notice what you observed where there is a gray empty tile until the new one loads. 🤔 I agree that further refactoring/commenting would be nice (ideally the code should speak for itself) although I must say I'd be pretty happy to get the code to a full working lag-less state before proceeding with that. |
Yes, I don't want to hold changed up at all, I only mean short comments if there's any bits that help in the interim, not an overhaul of docs or anything! That can sometimes help others spot problems reviewing, and thinking of any flaws in the future etc, and as mentioned, just a bonus, not core to this change. The grey tiles issue I saw on Chrome release mode, I haven't had chance to test on a mobile or anything yet. I could see there are occasions in other example pages where none-current zoom scaled tiles are used, but not on the animated controller...(speed of zoom or something if it's a couple of zoom levels out ?) |
I think I can see that in the new code, abortLoading() gets called, and the old tiles (eg from zoom level 5) seem to have a I'm a bit confused though, as if I look at the home page, I can see in tile_layer.dart that |
I think I have an idea what the problem may be.... Each tile we want, we do a
Now, _tileReady is used as a callback, and when that runs, it will check ask the TileManage for the tile..
(which uses _tiles behind the scenes). So first time around, there's a delay, the callback gets called lets set 50ms later, all is fine. However, what happens when the tile is already kinda previous loaded, so the app has it in cache somewhere or something like that. So I think Erm I think....I'm not sure of an elegant solution to test that, and running out of time though... |
Ok, what happens for you if we swap...
With
Does that get around the issues you were seeing as well ? Edit: I'm not entirely sure it is a race condition so maybe we can remove the comment if incorrect, but my brains given up for the day :D. |
@ibrierley Nice digging! That was the cause of the problem. On a throttled connection there was enough time for the tile to be added before the loading finished but on a fast connection or with the tile images cached the That change has been made now 👍 . |
Describe The Bug
When doing animated panning in flutter web using the example app (Animated Mapcontroller page) the markers (and any other non tile layer) seem to jitter against the map tiles.
Expected Behavior
The markers and other non tile layers should move together with the tile layer.
Screenshots & Recordings
flutter-map-panning-jitter.mp4
Additional Information
In the example I slowed the animation to 5 seconds to make the issue more obvious. I have not observed this issue when running the example on the Android emulator, only with flutter web on chrome. This is encountered both using the latest published version of flutter_map as well as
master
. Flutter version2.10.5
.When I run in release mode the effect is more subtle but there is still jittering. In any case the movement of the markers and the map tiles should be synchronised so that any jitter/jank should affect them together.
Doctors Report
To Reproduce
Steps to reproduce the behavior:
Severity
This will help us to label the issue quicker and decide what needs attention first. Only choose fatal if the entire app crashes, otherwise choose non-fatal.
Frequency/Rarity
This will help us to label the issue quicker and decide what needs attention first.
Applicable Platforms
Only select those that you've tested on - one or more. If possible, test on a variety of platforms.
The text was updated successfully, but these errors were encountered: