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

Run bevy systems in wasm even when the tab is not focused #13368

Open
cBournhonesque opened this issue May 14, 2024 · 4 comments
Open

Run bevy systems in wasm even when the tab is not focused #13368

cBournhonesque opened this issue May 14, 2024 · 4 comments
Labels
C-Enhancement A new feature O-Web Specific to web (WASM) builds S-Needs-Design This issue requires design work to think about how it would best be accomplished X-Contentious There are nontrivial implications that should be thought through

Comments

@cBournhonesque
Copy link
Contributor

What problem does this solve or what need does it fill?

It seems like if the user switches to a different tab, the bevy app will basically freeze and stop getting updated.

This seems to be because running the schedule in wasm is tied to requestAnimationFrame (https://developer.mozilla.org/en-US/docs/Web/API/window/requestAnimationFrame) calls which are made by winit in the winit_runner.

A potential solution would be:

  • if the tab is focused, keep the current scheduling logic
  • if the tab is not focused, update the schedule at fixed intervals (for example 60Hz(
@cBournhonesque cBournhonesque added C-Enhancement A new feature O-Web Specific to web (WASM) builds S-Needs-Triage This issue needs to be labelled labels May 14, 2024
@Nul-led
Copy link

Nul-led commented May 14, 2024

To add to this, while unfocused, bevy could run in headless mode (meaning no user io / rendering and input need to be collected).

Implementation wise this could make use of various web-apis such as setTimeout, setInterval, requestIdleCallback, queueMicrotask and Web Workers.

@jabuwu
Copy link
Contributor

jabuwu commented May 15, 2024

For posterity...

The comment in winit is a bit misleading. It says the strategy "is not affected by browser throttling", but this isn't always true. This seems to be the culprit: https://developer.mozilla.org/en-US/docs/Web/API/Scheduler/postTask#delaying_tasks
If a delay is set, the task will get scheduled with setTimeout, and we're back to throttle town. ControlFlow::WaitUntil will set a delay.
Using ControlFlow::Poll will cause the background tabs to stop throttling. I was able to check this by changing the value here to use poll and using bevy::winit::UpdateMode::Continuous:

event_loop.set_control_flow(ControlFlow::Wait);

Interestingly, in my testing with Poll, requestIdleCallback works pretty well but eventually stops updating in the background tab. Scheduler.postTask stalls out really quickly when delay > 0 and stops updating. setTimeout doesn't throttle ever, like I expect it to. Scheduler.postTask with delay = 0 never stalls out (but maybe starves the browser? not sure how rendering/vsync fits into all this)

https://discord.com/channels/691052431525675048/750833140746158140/1240217724354039858

It seems this is achievable right now by using ControlFlow::Poll and PollStrategy::Scheduler. Not sure the adverse effects of this change. Warrants more investigation. 😁

@jabuwu
Copy link
Contributor

jabuwu commented May 15, 2024

For this specific problem, I think web workers might be best. Spawning a web worker and having it run the setTimeout instead results in much faster and more accurate intervals, and web workers don't get throttled the same way browser tabs do. A postMessage from a web worker to a browser tabs wakes it immediately. The scheduler solution might be okay, but browser support isn't great

Unfortunately, at this point, winit doesn't support that strategy. It could probably be added as one.

Although, the issue that originally implemented scheduler with setTimeout fallback mentions a trick that might explain the results I was seeing with setTimeout: rust-windowing/winit#3044

Not sure I understand what that trick is. 🙂 Maybe it's also related to the postMessage it uses.

Also, regarding vsync and requestAnimationFrame: rust-windowing/winit#2880

@alice-i-cecile alice-i-cecile added X-Contentious There are nontrivial implications that should be thought through S-Needs-Design This issue requires design work to think about how it would best be accomplished and removed S-Needs-Triage This issue needs to be labelled labels May 21, 2024
@cBournhonesque
Copy link
Contributor Author

https://github.com/Nul-led/bevy_web_keepalive/tree/main fixes this issue for now

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
C-Enhancement A new feature O-Web Specific to web (WASM) builds S-Needs-Design This issue requires design work to think about how it would best be accomplished X-Contentious There are nontrivial implications that should be thought through
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants