-
-
Notifications
You must be signed in to change notification settings - Fork 717
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
Strategy for tile-prefetching during camera-movement #116
Comments
The target of the PoC was not to provide a final feature, but to test the feasibility and benchmark the WorkBox dynamic precaching vs vanilla one. That's why the tile logic is that simple, as it only takes into account pan & zoom prediction in a coarse way 🤷 Regardless that whiny side note 🤣 , using dynamic precaching for |
I have started working on an approach to add this feature to MapLibre. It is a bit of a mess because service workers and bundlers are still getting to know each other and I am a vanilla-JS guy. But that's just dev stuff, not the code itself. 🤓 The starting idea is to attach a service worker that will remain asleep till the user uses any "moving" function where the destination is provided, so we can build all the logic ( The very first version of the precaching is intended to hijack those moving functions and start precaching as soon as they are called. And which tiles are supposed to be precached (eventually)?
This way, the "focus area" of the map will be perfectly loaded and rendered during the animation, and the final scenario will be ready to welcome the user camera as it arrives. Taking into account the pitch and bearing at every frame of the animation to estimate the tiles in the viewport would imply heavy calculations that might nullify the precaching advantage, so they are out of my scope in this first version |
I think this is a great idea. I know that our style is probably too complicated to be rendered fast, and it won't show up while animating the flyto, but it would be great to prioritize the final tiles at the destination. For us at least... |
First swerve: moving form
|
News!
|
Nice work! I would be interested to know more about this. |
So, that's it 🤓 I have built a tiny experimental plugin for tiles preloading at https://github.com/AbelVM/maplibre-preload Please read the |
This issue is stale because it has been open 60 days with no activity. Remove stale label or comment or this will be closed in 7 days. |
Should this plugin be added to https://github.com/maplibre/maplibre-gl-js-docs/blob/main/docs/data/plugins.json and/or https://github.com/maplibre/awesome-maplibre before closing this issue? |
@AbelVM please decide if and how you would like to publish the tiny plugin you wrote... |
There is a pending PR in the Awesome List, actually: maplibre/awesome-maplibre#4 But adding it to the plugins list might give it more visibility and maybe * someone * helps turning it prod-quality and adding it to main branch 🙂 |
Upstream mapbox is getting this feature right now: mapbox/mapbox-gl-js#11328 Some thoughts on their proposed implementation:
|
I think the most valuable UX related to this feature is that the map is "there" when you arrive to the destination. |
My tiny plugin already has that kind of pattern, you can call It would be easy to overload the original methods with (an improved version of) my code, I just tried to be the least invasive as possible in the plugin |
I think it will be very useful UX to precache the flight path, and not just the destination. If we were to animate from London to New York, it will be quite disorienting if we're unable to see much of the zoom-out, travel and zoom-in between these two destinations. For reference, OpenLayers has a very neat implementation: |
Hmmm... It looks like they preload lower (z-n) resolution tiles if the z tiles are not cached: Worths a look 🤔 |
Hi, this plugin sounds like something I need. My app has few flyto points on the map, but when working on 4K display it is very laggy. However I can't make your tiny plugin to work with my setup. I set up my map with reactmap-gl and maplibre. How should I install maplibre-preload to work with reactmap-gl? I import the built package to index.js or App.js but I don't see cachedFlyTo neither under map nor map.getMap(). Can you help? |
Can you share a stackblitz or jsbin? |
Here is a stackblitz: https://stackblitz.com/edit/github-kut1lo?file=src/index.js I simplified it for testing purpose. I tried importing bundled module and installing plugin as node_module with: Neither works. How should I do it? |
Can we close this issue? I think the plugin is a good enough solution at this point... |
I think we should still have this feature natively in maplibre. The plugin only primes the browser cache, however, this will not work if the cache is disabled or the server disabled caching (such as people who generate tiles dynamically). For these cases, it will double the server workload and the bandwidth to download tiles. A native implementation would only have to fetch tiles once, and it could also start preprocessing tiles right away (creating necessary GL buffers etc.). This would remove a lot of the micro-stutter people observe when moving the camera. The plugin is a nice hack for some use-cases, but prefetching of tiles should be a core feature of maplibre. |
I totally agree with @JannikGM , we need to smooth the user experience of As previously mentioned, the strategy used by OpenLayers worths a look
In order to save bandwidth and load times, looks like they preload tiles at lower zoom levels for the target and crossing area and over-zoom them to the current map zoom, and once arrived, gracefully swapping them when final tiles of the target area are loaded. |
Fair enough. |
Hey folks I wanted to share what the experience looks like right now on a good internet connection for the example where we fly to specific locations based on the scroll position here https://maplibre.org/maplibre-gl-js/docs/examples/scroll-fly-to/ Screenshare.-.2023-10-05.12.17.15.PM.webmFor these map story-telling use cases (even without terrain or pitched camera angles) maplibre-gl-js struggles to deliver a good user experience out of the box. |
Regardless of your bandwidth, concurrent connections to the same server are limited to 6 in your browser, so, if you pan/zoom too fast, you're just sending and canceling lots of requests on the fly, as the tiles are still downloading when they are tagged as not needed (out of the viewport) and their requests canceled. So, yep, this is a big issue that we should look into imho. |
How do I set this pluginup in my typscript react app where I have my map initalized in another class? |
Only on http 1.X I guess.... |
Has there been any progress on this issue? I also don't get the plugin to work properly in my environment - only "Movement has finished before preloading" gets triggered. |
This project is just a PoC, quite naive. If there's a real interest on this feature, we should get serious, study the OpenLayers strategy (as it looks promising), and push this feature to MapLibre itself. Any opinion @HarelM ? |
There are strong forces to keep the bundle size small and so if this is possible using a plugin without a lot of "hacking" I think it can be a good solution. |
For my usecase (Storymaps) I need this feature, otherwise flyTo is completly useless. As already mentioned the example https://maplibre.org/maplibre-gl-js/docs/examples/scroll-fly-to/ does not really work smoothly without precaching. My workaround will be to preload the tiles programmatically when the site loads as I have an already specified "flight-path". |
FWIW, IMO, this should be considered integral to MapLibre. One could even say that the flyTo feature right now is half implemented since it doesn't really work for most users. The cache behaviour is crucial to the UX. But I do take your point on the bundle size. |
Looking at their code will infringe their copyright rules. I would advise against it. |
Instead of Mapbox, check OpenLayers approach: |
This PR might be of future use for this functionality: #4750 |
As part of the globe branch, we have moved all the tile logic to separate files so that we will be able to improve and change strategies better. |
Happy to help, as soon as I'm familiar with the new tiles code |
We often use
flyTo
, but maplibre doesn't seem to be smart enough to prefetch tiles along the animation path.The same is true for user mouse-movement (pan / zoom / rotate).
Ideally, the map would extrapolate where the map is going to render in the near future, so it can already load tiles.
When combined with a small
delay
in theAnimationOptions
this could be used to prefetch before the movement even starts.@AbelVM had recently shown a "hack" on maplibre Slack, which prefetches neighbouring tiles in the browser-cache: https://github.com/AbelVM/mapworkbox
Even this naive brute-force strategy (which doesn't respect camera movement direction) shows that better prefetching can have a performance impact.
The text was updated successfully, but these errors were encountered: