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

[feat] Allow disable background throttling #5250

Open
mantou132 opened this issue Sep 21, 2022 · 16 comments
Open

[feat] Allow disable background throttling #5250

mantou132 opened this issue Sep 21, 2022 · 16 comments
Labels
status: upstream This issue is blocked by upstream dependencies and we need to wait or contribute upstream fixes type: feature request

Comments

@mantou132
Copy link

Describe the problem

When the APP minimizes, the webview timer will be throttling.

Describe the solution you'd like

Electorn has webPreferences.backgroundThrottling options

https://www.electronjs.org/docs/latest/api/browser-window#new-browserwindowoptions

Alternatives considered

No response

Additional context

Related: electron/electron#1786

@FabianLars
Copy link
Member

Sooo, i researched this topic 2 times already. Once for #5147 and a few weeks before that in context of a discord thread.
And it really doesn't look good. The webviews don't have APIs for this at all and of course we don't have as much control over the engines as electron does -> their solution is irrelevant for us :(
Here's the most relevant upstream issue i could find: MicrosoftEdge/WebView2Feedback#1172

The only thing left that i couldn't figure out (though it didn't look good either) is to try to make it think it's visible and focused by some weird window manipulation, but that's beyond me - cc @amrbashir

tldr: Don't wait for this feature :/

@amrbashir
Copy link
Member

This only affects Windows or other platforms as well?

try to make it think it's visible and focused by some weird window manipulation

On Windows, we don't hide the webview when the window is minimized (although we probably should) and yet the timers are being throttled. So I don't think we can do much here without explicit support in the webviews.

@FabianLars
Copy link
Member

This question was always asked in the context of Windows only. No idea how the other webiews actually behave tho

@amrbashir amrbashir added the status: upstream This issue is blocked by upstream dependencies and we need to wait or contribute upstream fixes label Sep 21, 2022
@chen-gaoyuan
Copy link

Sooo, i researched this topic 2 times already. Once for #5147 and a few weeks before that in context of a discord thread. And it really doesn't look good. The webviews don't have APIs for this at all and of course we don't have as much control over the engines as electron does -> their solution is irrelevant for us :( Here's the most relevant upstream issue i could find: MicrosoftEdge/WebView2Feedback#1172

The only thing left that i couldn't figure out (though it didn't look good either) is to try to make it think it's visible and focused by some weird window manipulation, but that's beyond me - cc @amrbashir

tldr: Don't wait for this feature :/
查了几天资料, 原因就是浏览器将不在前台的页面休眠了, Chromium最长会一分钟才唤醒一次, 导致setInterval不管设置多小的值也要等1分钟执行一次.
现在有几种方案:

  1. 最简单的方案, 使用Web Worker 中调用setInterval, 然后发送事件通知app. 但是偶尔也会等几秒才唤醒一次Web Worker.
  2. 保持一个WebSocket连接, 当有网络连接存在时Chromium不会将页面休眠. 这个必须要tauri来实现, 现在无法使用原生的WebSocket!
    希望这个问题能够得到完美的解决!
    谢谢!

@eugenehp
Copy link
Contributor

eugenehp commented Apr 2, 2024

Doesn't seem like @chen-gaoyuan's idea about WebSockets and Web Worker works that well.

Did anybody solve this issue on their end?

@venkr
Copy link

venkr commented Apr 18, 2024

It looks like macOS recently added support for picking between {throttle, suspend, none}:
https://developer.apple.com/documentation/webkit/wkpreferences/4173317-inactiveschedulingpolicy

I'm not sure if this actually works, or is the thing we're looking for, but in theory, setting it to .none in wry somewhere around the other config logic (https://github.com/tauri-apps/wry/blob/3e3d59cd4f79c21571e503a5bf80d4d54a654a38/src/wkwebview/mod.rs#L457) should work (for macOS).

@snatvb
Copy link

snatvb commented Apr 24, 2024

Still no option to avoid it? It's blocker for me, maybe needs to migrate to electron, that I don't want :(

@arialpew
Copy link

arialpew commented May 20, 2024

Still no option to avoid it? It's blocker for me, maybe needs to migrate to electron, that I don't want :(

Minimized application should not rely on interval and timers precision.

If you really need that behavior, use timers that run in background worker : https://www.npmjs.com/package/worker-timers - this should solve all of your issues.

@eugenehp
Copy link
Contributor

FYI: We opted out to use a web socket server that does a heartbeat to a web worker in the browser instead. It's a hack, but it solved it for now.

@snatvb
Copy link

snatvb commented May 20, 2024

Minimized application should not rely on interval and timers precision.

If you really need that behavior, use timers that run in background worker : https://www.npmjs.com/package/worker-timers - this should solve all of your issues.

Just I make a game, that works online, and there is exists animations :)

@bastiankistner
Copy link

Hi there! I'm building a tauri app that relies on a WebSocket connection. It works fine until I hide my window, which can be unhidden through a tray icon, and put my machine into sleep mode (MacOS). After several minutes, when I wake it up again, the WebSocket connection will not be reestablished unless I unhide the window. Only then will it reconnect. I assume that this is because the connection drops while my machine is sleeping. And when it comes back up, the fact that the connection is lost, will trigger Webkit to fully suspend the tab before the reconnect can happen.

I've tried a lot of hacks like having a local WebRTC ping pong, playing a muted audio file, creating an audio on demand with an OscillatorNode or using an infinitely pending WebLock transaction. Nothing worked on MacOS. So I tried to implement a draft for leveraging the WKInactiveSchedulingPolicy, which seems to finally resolve my issue. Timers are still being throttled down to ~2 seconds. But at least the tabs are no longer fully suspended.

In my case the only solution I see is putting everything into a worker. But since I cannot access tauri IPC from within workers, I'd need a local server that could be passed messages and handle them. But I'm also using pglite and several other features that would then have to be moved down to system level. I do agree that tab suspension is a great feature for regular browser users. But in case of apps that are based on tauri, it should be up the developer to decide when to free resources and handle them properly. Otherwise, many of the great features we have at hand with browser capabilities would become unusable for long running applications.

The draft for the background throttling can be found here:

This only works for Webkit/MacOS yet.

For windows, as mentioned in MicrosoftEdge/WebView2Feedback#1172, there is still no way to handle this properly it seems. But according to https://techcommunity.microsoft.com/discussions/edgeinsiderannouncements/sleeping-tabs-faq/1705434 using a simple WebLock transaction should do the trick (at least to avoid having tasks fully suspended).

Here is a gist without using a framework: https://gist.github.com/bastiankistner/5739d8fc36239113b91ac52711c4101b
and here one for react: https://gist.github.com/bastiankistner/721fbd14cb7dd850f76df0985f394e75

@FabianLars do you think this would be something that could make it into tauri? If so, do you have any suggestions for improvements before I could open a PR?

@snatvb
Copy link

snatvb commented Jan 3, 2025

But in case of apps that are based on tauri, it should be up the developer to decide when to free resources and handle them properly. Otherwise, many of the great features we have at hand with browser capabilities would become unusable for long running applications.

Totaly agree

@bastiankistner
Copy link

Just wanted to mention that I've now tested multiple times if the issue with the dropped connection due to the suspended (hidden) window persists or is finally gone. And I can happily confirm that using the inactivity policy change resolves it perfectly! Would be great if that could be added to tauri. I'm certain there are many things I'd need to add / change but I'm absolutely willing to push this forward!

@eugenehp
Copy link
Contributor

eugenehp commented Jan 3, 2025

@bastiankistner a PR would definitely help.

@bastiankistner
Copy link

I've opened two PRs, one for wry and one for tauri-apps.

tauri-apps/wry#1445
#12181

@eugenehp
Copy link
Contributor

eugenehp commented Jan 4, 2025

@FabianLars could you please take a look and let us know what's needed to get it merged. Happy new year!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
status: upstream This issue is blocked by upstream dependencies and we need to wait or contribute upstream fixes type: feature request
Projects
Status: 📬Proposal
Development

No branches or pull requests

9 participants