CPU spikes when running the unfocused app in web
Bevy version
This is happening only in Bevy 0.13.x, since the recent refactor to winit 0.29.
Relevant system information
Tested on Windows 11 and MacOS, using Chrome. I've not been able to reproduce it in Firefox, but it might be only because of different rendering speed, since the error in non-deterministic.
What you did
- Run the
low-powerexample in WASM - Unfocus the page (it works best if switching to a different tab in the browser)
- Check the CPU usage (e.g. in ActivityMonitor): it spikes up to 400% more than the default focused behaviour.
What went wrong
The expected result should be that:
- in game mode, it should continue to use the same amount of CPU (i.e. continuously running) => OK
- in reactive mode, without RequestRedraw, it should use a very low amount of CPU in unfocused mode
- in reactive mode, with RequestRedraw, I'm not really sure what's the expected behavior.
What I discovered
-
window.request_redraw()is called depending on the visibility of the window. This is discouraged by winit, and it doesn't really help because the focused/unfocused state is not the same thing as the visible/invisible one. The winit control_flow example doesn't use the visibility as a check to redraw the window. - this should run only if the wait timeout has elapsed (I think).
- the
runner_state.wait_elapsedshould only be updated in NewEvents (and never reset manually like here). This is because a very common flow isNewEvents=>RedrawRequested=>AboutToWait, but even if the first sets the wait_elapsed to true, this would be immediately reset in the second and thus irrelevant in the third.
As sidenotes to be considered:
- the
WinitAppRunnerStatecontains theActiveState(that tracks the current app state), and also values related to rendering and waiting, more linked to the event loop. IMO these two parts should be decoupled as they don't touch each other and change for different reasons. - the UpdateMode::Continuous should be removed from WASM as it doesn't make sense
Does https://github.com/bevyengine/bevy/pull/12607 fix this for you?
No, unfortunately that has a regression when running with UpdateMode::Continuous (not redrawing). This fixes it but needs to be verified on all platforms, and I don't really know how.
Discussion details here.