Open manzt opened 3 years ago
I think this seems very reasonable, thanks for bringing it up.
Just spitballing/trying to contribute, but it seems that we should probably do something like powers-of-2 maybe? Like 16 <-> 256, 8 <-> 512, 4 <-> 1024 (or one power lower). This seems reasonable (or we could go one power lower) since the worst case for 1024 on an average computer screen (~1000 x 2000), for example, is that you need to load 9 tiles to fill the viewport so roughly half of that seems reasonable. We could also calculate based on the viewport size, although this can change if someone resizes the window.
In fact, related to what you mention about equivalent numbers of tiles, it might even make sense to do powers of 4
I guess screens are rectangular so not exactly powers of 4, but something larger than 2 is necessary for what I'm saying.
My vote is to experiment with some power-of-two tile sizes and see if anything generalizes. It's hard-coded at 10
for now for all tile sizes, so anything makes that lower for larger tiles is better than what we have currently. For that reason, for now I think a heuristic based only on tile size makes sense. We can experiment with more sophisticated things (e.g. number of selections per request, data type, current viewport) in the future.
We can keep maxRequests
with no default. If provided, it overrides everything, otherwise we do something coarse. It's a complex relationship between how interaction influences number of requests and when deck.gl will decided to cancel requests.
For instance, if you've stopped zooming, you basically want maxRequests===Infinity
because you want deck.gl to fill the viewport as fast as possible. But when zooming, you want to cancel as many requests from the zoom level you're not on as possible. We have to use maxRequests
to optimize for the latter, but it feels like something deck.gl might be able to handle as well.
For images with small tile sizes, there is a noticeable improvement in performance when using the TileLayer, but this isn't reflected as much for images with large tiles. Why? This isn't what we measured in our benchmark and it's worth exploring.
Currently we expose
maxRequests
as a prop to limit the number of concurrent requests from deck.gl. To my knowledge we just use the default of10
in Avivator, Vitessce, and Vizarr regardless of the image tile size. It occurred to me this morning that 10 requests for 256x256 tiles!=
10 requests for 1024x1024 tiles.Deck.gl will only start cancelling requests if
maxRequests
is exceeded. One 1024x1024 tile takes is the same spatial region as 16 256x256 tiles. For one 1024x1024 region, deck.gl can choose to cancel requests when tile sizes are 256x256. In contrast, it requires at least concurrent 10 requests for 1024x1024 regions (or the equivalent of 160 256x256 tiles) before deck.gl can cancel requests when the tilesize is 1024x1024.Image pyramids are often less than 10 levels, and if you have a small screen, you could end up requesting 1 tile per level when zooming and never have a request cancelled.
Preferred solution
Set
maxRequests
to be much smaller by default. Open Viv and try setting it to2
, for example. You'll be blown away with how much better some of the examples are in Avivator. This is very simple and mimics the current API. My preference is to have a smarter default that works well in most cases.I think the real question is what user are we optimizing for by default. If it's loading a fix viewport the fastest, having a large
maxRequests
makes sense. But for exploratory navigation, we want to be able to cancel as many requests as possible when a user is panning and zooming so that when they reach a region it loads quickly.Possible alternatives
Come up with some heuristic for
maxRequests
that varies with tiles size. I am hesitant to suggest this alternative because it's complicated and it isn't clear to me what a new API would look like. EvenmaxRequests
is somewhat confusing becauseloaderSelection
influences how many requests are actually made per "request". If we go this route, I would suggest not exposing an API.