Add a preference to allow disabling the throttling of "requestAnimationFrame"
Categories
(Core :: Layout, enhancement)
Tracking
()
Tracking | Status | |
---|---|---|
firefox136 | --- | fixed |
People
(Reporter: whimboo, Assigned: emilio)
References
(Blocks 2 open bugs)
Details
Attachments
(1 file, 1 obsolete file)
For testing purposes, I would like to propose adding a mechanism to disable the throttling of window.requestAnimationFrame
invocations when a tab is in the background. Currently, background tabs throttle requestAnimationFrame
to 1 frame per second. Additionally, I observe that each invocation introduce a cumulative factor of 2, which further increases the slowdown for code relying on this method.
pw:browser [pid=53296][out] 1736338119512 RemoteAgent DEBUG WebDriverBiDiConnection 16d6a9a7-9754-4f27-b9e7-3d96dc2f096a <- {"type":"event","method":"log.entryAdded","params":{"type":"console","method":"log","source":{"realm":"d6556ad5-8984-41d8-9427-cda4c19893fd","context":"fe3776fd-358b-4866-bf70-83c656e519f7"},"args":[{"type":"string","value":"\n** animation frame count 30 http://localhost:8907/empty.html\n"}],"level":"info","text":"\n** animation frame count 30 http://localhost:8907/empty.html\n","timestamp":1736338119510}} +994ms
pw:browser [pid=53296][out] 1736338120513 RemoteAgent DEBUG WebDriverBiDiConnection 16d6a9a7-9754-4f27-b9e7-3d96dc2f096a <- {"type":"event","method":"log.entryAdded","params":{"type":"console","method":"log","source":{"realm":"d6556ad5-8984-41d8-9427-cda4c19893fd","context":"fe3776fd-358b-4866-bf70-83c656e519f7"},"args":[{"type":"string","value":"\n** animation frame count 29 http://localhost:8907/empty.html\n"}],"level":"info","text":"\n** animation frame count 29 http://localhost:8907/empty.html\n","timestamp":1736338120513}} +1s
pw:browser [pid=53296][out] 1736338122519 RemoteAgent DEBUG WebDriverBiDiConnection 16d6a9a7-9754-4f27-b9e7-3d96dc2f096a <- {"type":"event","method":"log.entryAdded","params":{"type":"console","method":"log","source":{"realm":"d6556ad5-8984-41d8-9427-cda4c19893fd","context":"fe3776fd-358b-4866-bf70-83c656e519f7"},"args":[{"type":"string","value":"\n** animation frame count 28 http://localhost:8907/empty.html\n"}],"level":"info","text":"\n** animation frame count 28 http://localhost:8907/empty.html\n","timestamp":1736338122518}} +2s
pw:browser [pid=53296][out] 1736338126523 RemoteAgent DEBUG WebDriverBiDiConnection 16d6a9a7-9754-4f27-b9e7-3d96dc2f096a <- {"type":"event","method":"log.entryAdded","params":{"type":"console","method":"log","source":{"realm":"d6556ad5-8984-41d8-9427-cda4c19893fd","context":"fe3776fd-358b-4866-bf70-83c656e519f7"},"args":[{"type":"string","value":"\n** animation frame count 27 http://localhost:8907/empty.html\n"}],"level":"info","text":"\n** animation frame count 27 http://localhost:8907/empty.html\n","timestamp":1736338126522}} +4s
The motivation for this request originates from the needs of testing tools, such as Playwright, which run tests in parallel across multiple user contexts (containers). These tools require consistent execution speeds for all tests, regardless of whether a tab is in the foreground or background. With throttling in place, tests running in background tabs experience significant slowdowns, often leading to timeouts and degraded testing performance.
Assignee | ||
Comment 1•2 months ago
|
||
Do you want to also stop throttling stuff like out-of-view iframes? They use the same mechanism...
Reporter | ||
Comment 2•2 months ago
|
||
When it's as well affecting rendering via requestAnimationFrame
throttling then I would say it should be included as well, yes.
Assignee | ||
Comment 3•2 months ago
|
||
Well but those get throttled on foreground tabs as well right now.
Reporter | ||
Comment 4•2 months ago
|
||
Oh I see. Is layout.throttle_in_process_iframes
the preference then to control out-of-view iframe throttling? If yes, we probably should keep it separate especially when it affects the active tab as well.
Reporter | ||
Comment 5•1 months ago
|
||
Emilio, is there anything that I could help with? If yes, where would the preference check have to be added exactly? Thanks.
Assignee | ||
Comment 6•1 months ago
|
||
Updated•1 months ago
|
Assignee | ||
Comment 7•1 months ago
|
||
Updated•1 months ago
|
Assignee | ||
Comment 8•1 months ago
|
||
Can you confirm comment 7 works for you?
Reporter | ||
Comment 9•1 month ago
|
||
Because I cannot build myself at the moment I've pushed a try build for MacOS testing here:
https://treeherder.mozilla.org/jobs?repo=try&revision=69fa31f9d9de37c7d7fc50a5f837d5e79d993121
Once builds are available I'll test. Thanks a lot for your help Emilio!
Reporter | ||
Comment 10•1 month ago
|
||
Emilio, this is not working as expected. Here is what I can see:
- Setting
'layout.top-level-always-active': true
will execute the rAF callbacks once per second still. - Setting additionally
'layout.throttled_frame_rate': 60
will cause rAF callback to be run with that rate
I assume that with setting layout.top-level-always-active
to true
we should not need the other preference, right?
Assignee | ||
Comment 11•1 month ago
|
||
There was another check for rAF specific (not refresh-driver-specific) throttling, try again? I've confirmed that with this page:
<!doctype html>
<pre id="log"></pre>
<script>
let frames = [];
function logRate() {
let averageFrameDuration = (frames[frames.length - 1] - frames[0]) / frames.length;
log.appendChild(document.createTextNode((1000 / averageFrameDuration) + "fps\n"));
setTimeout(logRate, 1000);
}
requestAnimationFrame(function f(t) {
frames.push(t);
if (frames.length > 5) {
frames.shift();
}
if (frames.length == 1) {
setTimeout(logRate);
}
requestAnimationFrame(f);
});
</script>
rAF keeps the right pace with that pref on.
Reporter | ||
Comment 12•1 month ago
|
||
This looks fine! When I checked the additional if condition I noticed that iframe throttling is checked later on so that enabling this new pref will also make the above case work when run inside an iframe. That is great! I cannot say if there might be side-effects that this pref might cause.
Comment 13•1 month ago
|
||
Comment 14•1 month ago
|
||
bugherder |
Reporter | ||
Comment 15•1 month ago
|
||
Thanks Emilio! This works great in a Nightly build.
Comment 16•1 month ago
|
||
(In reply to Emilio Cobos Álvarez (:emilio) from comment #11)
There was another check for rAF specific (not refresh-driver-specific) throttling, try again? I've confirmed that with this page:
FYI: that test is a bit off: here's a fixed version
<!doctype html>
<pre id="log"></pre>
<script>
let frames = [];
function logRate() {
let averageFrameDuration = (frames[frames.length - 1] - frames[0]) / (frames.length - 1);
log.textContent += `${averageFrameDuration} ms ${1000 / averageFrameDuration} fps\n`;
setTimeout(logRate, 1000);
}
requestAnimationFrame(function f(t) {
frames.push(t);
if (frames.length > 5) {
frames.shift();
}
if (frames.length == 2) {
setTimeout(logRate);
}
requestAnimationFrame(f);
});
</script>
Description
•