-
Notifications
You must be signed in to change notification settings - Fork 2.2k
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
Raster tile loading blocking UI, FPS < 2.0 #6643
Comments
This seems to be some kind of regression with the source cache logic — most of the time is spend figuring out which tiles to show, not actual rendering or loading. Investigating now. |
Looks like it's not a regression, just an algorithm that dramatically slows down quadratically when the tile size goes down — it was only optimized for vector tiles, where you typically only see 6-7 tiles on the screen. Thinking about a faster one now... |
OK, I have a good lead on this. Will submit a PR tomorrow. |
Turns out that the jank on raster layers is currently dominated by XHR requests, which we use to load images since #1472 because of an issue with browsers not fully respecting Since the original fix with XHR image loads was introduced specifically to fix sprite updates, and most image loads don't have short cache spans, I wonder if we can use some kind of a mixed approach. For example, a raster tile source would do its first request with XHR-based getImage, see if |
Thanks, it's great to see this! Is there any use case for super frequently updating raster tiles? Like satellite images are the slowest changing data in a map platform, aren't they? If it is seriously needed for any use case, I'd recommend adding a tileXHR or tileCache or something similar to rasterSource and letting the developers choose it manually. |
@hyperknot I feel like letting the developers choose would expose too much internal detail for a thing that should just work well automatically. So let's try to exhaust automatic heuristics first and resort to an explicit option if it doesn't work. |
I was going to say we could probably just have tile requests always use For browsers that support it, we could try out an XHR with |
@jfirebaugh do you think it's worth the added complexity? As I see neither does Safari nor Edge supports it, while a simple Image.src is probably super optimised in every browser. |
@jfirebaugh this likely won't help — looks like it's not the blob construction that's the bottleneck, but the XHR itself. Here's a screenshot from a stuttered frame (notice that all time is spent in
I think we could come up with a heuristic that supports this use case. E.g. if P.S. #6995 and #6998 are PRs that remove two other bottlenecks that I identified when researching this issue. |
Added a proposal for addressing this issue in #7008. @hyperknot try applying all three PRs (#7008, #6995, #6998) and let me know how the performance looks. |
I've merged all PRs (#6998 was already merged), and the image loading logic works perfectly, however the jankiness is still present (and can be up to 0.5 second). Here is a codepen with an updated build: |
OK, it seems to be depending on if the Developer Tools is open or not:
Unfortunately it's not possible to use the FPS meter without dev tools open, so it's a tricky case. But based on perception alone, the normal use case is about 10x better. |
@hyperknot awesome! It's also worth noting that 128px tiles are an extreme case due to so many requests — performance after the patches is pretty smooth with bigger tile sizes. |
Yes, solving this case also helped the normal satellite tiles work super smoothly, thanks a lot for tackling it! (I wouldn't consider this an extreme case, as there are only 4x tiles visible compared to Mapbox satellite (whose tile size is actually 256px)). |
For reference: https://bugs.chromium.org/p/chromium/issues/detail?id=348655. |
From #7008:
I've looked into how OpenLayers handles raster tile loading, and I believe the reason why their equivalent is fast is that they use a TileQueue data structure that makes sure there are never more than 16 tiles loading in parallel or requested at once in one frame. This makes it avoid requesting short-lived tiles that e.g. get requested on zoom in near the borders of the map and then immediately go off the view when zooming further during an animation. This might be a possible solution to this feature request #5482, and we should definitely explore a similar approach. |
This seems in a pretty good shape after #7497 and earlier improvements, so closing. |
mapbox-gl-js version: 0.45.0
browser: Chrome 66 / macOS
Link to Demonstration
(I tested using Chrome FPS meter)
example: https://zl761nnr3m.codesandbox.io/
code: https://codesandbox.io/s/zl761nnr3m
Expected Behavior
UI interactions should be smooth, independent of tile loadings in the background.
Actual Behavior
The UX is really bad with raster layers now. Chrome FPS meter regularly gets under 2.0 fps on my Macbook Pro.
I've almost finished porting a big codebase over to Mapbox GL viewer, but this one is puzzling me. Both Leaflet and OpenLayers can display raster maps at constant 58+ FPS. How is it possible that Mapbox GL can render the most complicated vector tile regions smoothly, but is breaking with simple raster tiles?
The text was updated successfully, but these errors were encountered: