Skip to content
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

Better default for maxRequests in TileLayer #396

Open
manzt opened this issue Mar 17, 2021 · 4 comments
Open

Better default for maxRequests in TileLayer #396

manzt opened this issue Mar 17, 2021 · 4 comments

Comments

@manzt
Copy link
Member

manzt commented Mar 17, 2021

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 of 10 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 to 2, 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. Even maxRequests is somewhat confusing because loaderSelection influences how many requests are actually made per "request". If we go this route, I would suggest not exposing an API.

@ilan-gold
Copy link
Collaborator

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.

@ilan-gold
Copy link
Collaborator

In fact, related to what you mention about equivalent numbers of tiles, it might even make sense to do powers of 4

@ilan-gold
Copy link
Collaborator

ilan-gold commented Mar 17, 2021

I guess screens are rectangular so not exactly powers of 4, but something larger than 2 is necessary for what I'm saying.

@manzt
Copy link
Member Author

manzt commented Mar 17, 2021

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants