electron: "backgroundThrottling: false" no longer affects requestAnimationFrame() in background applications
- Electron version: 1.5.0 thru 8.0.0
- Operating system: Mac OS Sierra 10.12.4, El Capitan 10.11.6, 11.2.3 Mac OS Big Sur
Expected behavior
Disabling background throttling should prevent the slowdowns/pausing of both animation frames and intervals/timeouts when the window is in the background.
For instance,
mainWindow = new BrowserWindow({
...
webPreferences: {
pageVisibility: true,
backgroundThrottling: false,
},
...
})
… should allow RAF to run without getting stopped or otherwise throttled when the window is in the background (minimized or completely obscured by other windows). Behavior specific to RAF on this issue was added in 0.37.6 (https://github.com/electron/electron/issues/4925)
Actual behavior
Behavior that depends on RAF calls will slow to a crawl when the window becomes obscured by other windows or is otherwise made a “background” window, behaving no differently whether backgroundThrottling is set to true or false. It reverts to normal behavior as soon as it becomes a foreground window again.
How to reproduce
Easiest to just use the test repo I put together.
git clone https://github.com/stickywes/test-electron-background-throttle.git
npm install
npm start
Workaround(s)
Use an older version of electron.
Versions below 1.5.0, such as 1.4.16, do not have this issue. The regression on this issue appears to begin with 1.5.0 onward.
Use setInterval()
westoncbb says: “setInterval() does work in the background with backgroundThrottling: false —so that may be a workaround for some.”
About this issue
- Original URL
- State: closed
- Created 7 years ago
- Reactions: 17
- Comments: 46 (7 by maintainers)
requestAnimationFrameis designed to run animations on screen, and as such is heavily linked to on-screen behaviour in chromium code (e.g. being tied to the refresh rate of the display that the frame is currently displayed on). If you need timers to run unthrottled in the background, usesetTimeoutorsetInterval, with thedisable-background-timer-throttlingswitch.requestAnimationFrameis not a timer.Hey, although @stickywes case may be more on the fringe I think my case is actually legitimate. I’m using captureStream to send a canvas through a WebRTC peer connection, which is blending some videos together to send it to the other peers. Previously I used backgroundThrottling set to false and a RAF loop to update the canvas. This no longer works and breaks my implementation. I would really prefer not to use an interval as it wouldn’t match the display refresh rate. Is there any alternative here?
I’d like to develop html canvas game. Multiplayer one at it too. Turn based. While opponents will wait for each others move, they will surely like to do a quick peek, into someone else’s websites. This breaks animation. Breaks my game too! And this bug is closed!? Oh no, it is alive, well, kicking and breaking peoples dreams! Edit: Its not just OS, Firefox has it too
is this problem fixed … I am also facing this in 6.1.11 I am capturing my app screen when its minimize the animation paused any way to fix this
Any updates on this issue?
This is the same using Electron version 4.0.6
@nornagon
setTimeoutisn’t a good enough workaround for this.requestAnimationFrameis designed to sync to screen refresh rates (source: article from 2012).setTimeoutdoes not have this ability.For applications which deal with realtime graphic rendering or @pedromcunha’s WebRTC case,
setTimeoutis not “appropriate” and that suggestion completely nerfs the point of having rAF in the first place.I’m in the process of porting my application modV from NW.js to Electron - I was really enjoying the Electron experience until I encountered this road bump.
My application runs an rAF loop in the main Window and draws to Canvas Elements in child Windows. If the main Window becomes obscured on macOS the main rAF loop is halted and output is not drawn to the child Windows.
Two potential solutions which are a little less than ideal (may help others):
Making the child Windows have their own rAF loop
Moving the draw loop to a Worker then using OffscreenCanvas to keep the loop running regardless of Window visibility
As you’ve said this was intended behaviour, would this be better off as a feature request (NW.js has a
--disable-raf-throttlingflag, for example) rather than an issue?After doing some research:
In commit https://github.com/electron/electron/commit/497f5a11994a1c9858afd6ab04ea3ae9b3b77b34 (a part of Electron v1.5.0), osr_render_widget_host_view_mac.mm was changed to reflect Chromium API changes. This could be what introduced the bug. But I might be wrong here because I don’t know low level Electron well enough. 😄
This is the associated Chromium change. Search for
browser_compositor_view_mac.mm.Additionally, the member variable
disable_hidden_set in atom_api_web_contents.cc is not found in the corresponding Chromium class or any class it inherits from, which is a little mind boggling. Where does Chromium use thedisable_hidden_property?If anyone can drop some knowledge on this, that’d be awesome.
Same problem here:
I have tried the webPreferences option ‘backgroundThrottling: false’, app.commandLine.appendSwitch(‘disable-renderer-backgrounding’), and win.setMinimizable(true) —in all cases requestAnimationFrame stops getting called when the window is inactive.
electron version: 1.6.11 OS: macOS El Capitan 10.11.6
Edit: setInterval() does work in the background with backgroundThrottling: false —so that may be a workaround for some.
One step toward a solution would be to provide an example that demonstrates the issue, and provide details like the Operating System and OS version you’re using.
It’s still not fixed! Using latest electron. This issue is so annoying. Aslo the lack of ownership of all the issues electron has. Literally every second feature has issues…
I pushed several updates and new releases of the demo project today, in order to support more modern Electron APIs since the original issue was posted.
I incremented major versions (eg.
npm install --save-dev electron@v^7.0.0) several steps and tested at each step, and the issue appears to have stopped at electron@^8.0.0 and above. I am not able to reproduce the issue from that point on (and when throttling is enabled, I get the expected error result).These tests were run on Mac OS Big Sur 11.2.3
Why is every second feature of electron not working properly? Its so annoying. Better not read the docs and get exited about features which don’t even exist.
And I don’t read any statement that the team is intending to fix this.
@Littlebigdondon Not sure, I never got round to making a patch file.
Will need to fork Electron, create the patch, push that to the fork and then follow the build instructions but pull from your fork instead.
I got busy between then and now with moving house so I haven’t had time to properly check this.
setInterval is an appropriate function to use for that use case; there’s nothing tying your LED display to the refresh rate of your monitor.
rAFis for when you want to be embedded in the browser’s paint cycle, which is irrelevant for your use case.Confirmed to reproduce on 2.0.x and 3.0.x, and
disable-background-timer-throttlingdoesn’t work around the issue.Any news of this issue? I currently still using electron 1.4.x but my user encounter some cpu/ram problem with webGL, wich are better managed in the 1.7/8. However my app has to still working during a workspace change or when it is minimized, i can’t sacrifice this feature for mac users.
I have tried :
without success.
It’s really annoying and this regression was introduced a long time ago. So if you can fix it ❤️
Don’t know if this will help, but I tried the repro on two environments:
Can’t reproduce on Windows 8 Can reproduce on El Capitan 10.11.6