Closed Bug 1940688 Opened 2 months ago Closed 1 month ago

Add a preference to allow disabling the throttling of "requestAnimationFrame"

Categories

(Core :: Layout, enhancement)

enhancement

Tracking

()

RESOLVED FIXED
136 Branch
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.

Do you want to also stop throttling stuff like out-of-view iframes? They use the same mechanism...

Flags: needinfo?(hskupin)

When it's as well affecting rendering via requestAnimationFrame throttling then I would say it should be included as well, yes.

Flags: needinfo?(hskupin)

Well but those get throttled on foreground tabs as well right now.

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.

Blocks: 1938385

Emilio, is there anything that I could help with? If yes, where would the preference check have to be added exactly? Thanks.

Flags: needinfo?(emilio)
Assignee: nobody → emilio
Status: NEW → ASSIGNED
Attachment #9446918 - Attachment is obsolete: true

Can you confirm comment 7 works for you?

Flags: needinfo?(emilio) → needinfo?(hskupin)

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!

Emilio, this is not working as expected. Here is what I can see:

  1. Setting 'layout.top-level-always-active': true will execute the rAF callbacks once per second still.
  2. 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-activeto true we should not need the other preference, right?

Flags: needinfo?(hskupin) → needinfo?(emilio)

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.

Flags: needinfo?(emilio) → needinfo?(hskupin)

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.

Flags: needinfo?(hskupin)
Blocks: 1917540
Pushed by ealvarez@mozilla.com: https://hg.mozilla.org/integration/autoland/rev/e47794b1117a Add a pref to make top level pages always active for the purpose of refresh driver throttling and such. r=layout-reviewers,tnikkel
Status: ASSIGNED → RESOLVED
Closed: 1 month ago
Resolution: --- → FIXED
Target Milestone: --- → 136 Branch

Thanks Emilio! This works great in a Nightly build.

(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>
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Created:
Updated:
Size: