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

setTimeout has a minimum delay of 1 second (or 15mn on mobile) in inactive tabs #2996

Closed
tomaka opened this issue Nov 10, 2022 · 2 comments · Fixed by #2999
Closed

setTimeout has a minimum delay of 1 second (or 15mn on mobile) in inactive tabs #2996

tomaka opened this issue Nov 10, 2022 · 2 comments · Fixed by #2999

Comments

@tomaka
Copy link
Contributor

tomaka commented Nov 10, 2022

https://developer.mozilla.org/en-US/docs/Web/API/setTimeout#timeouts_in_inactive_tabs

This was more or less known to me, but it's not something that we've actively taken into account until now.

The problem is that smoldot sometimes intentionally queues a task using setTimeout(..., 0) in order to intentionally yield back control to the browser so that it can run its events loop.
For example, when verifying warp sync fragments, smoldot will intentionally give control back to the browser between each fragment. There can be hundreds of fragments to verify. This wouldn't be a problem if the time between two fragments is very small, but if the minimum delay is 1 second, then it takes literally 100 seconds for an operation that would normally take 100ms or so.

Even when the tab is in the foreground, after 5 setTimeouts in a row, the minimum delay becomes 4ms:
https://developer.mozilla.org/en-US/docs/Web/API/setTimeout#nested_timeouts
Again, this is problematic if there are hundreds of fragments to verify one after the other.

@tomaka
Copy link
Contributor Author

tomaka commented Nov 10, 2022

We can use the Page Visibility API to determine when to intentionally yield or not.

@tomaka
Copy link
Contributor Author

tomaka commented Nov 10, 2022

Looking at the code, the situation is quite bad. For example, when a timer is finished or a message arrives on a socket, we don't immediately process it but instead we call setTimeout(..., 0) and the callback does the processing.

In general, the code assumes everywhere that setTimeout(..., 0) works as advertised.

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

Successfully merging a pull request may close this issue.

1 participant