Closed Bug 1815015 Opened 1 year ago Closed 1 year ago

SetTimeout callback is triggered very frequently in an unviewed tab process

Categories

(GeckoView :: General, defect, P1)

All
Android

Tracking

(firefox112 wontfix, firefox113 wontfix, firefox114 fixed)

RESOLVED FIXED
114 Branch
Tracking Status
firefox112 --- wontfix
firefox113 --- wontfix
firefox114 --- fixed

People

(Reporter: kaya, Assigned: kaya)

References

Details

(Whiteboard: [geckoview:m111] [geckoview:m112] [geckoview:m113] [geckoview:m114] [fxdroid] [foundation] Juno)

Attachments

(2 files, 1 obsolete file)

nsGlobalWindowInner::RunTimeoutHandler is continuously getting called from tab processes' that are in the background. "Background" here means that the tab process is created, url loaded but not viewed. To have this state, one can simply open a link from a website in a new tab and does not switch to that tab. In case the app is sent to background (e.g. screen is locked or device's home button is pressed etc.), the unviewed tab process still continuously firing the setTimeout callback.

This timeout runnable needs to be throttled. The method for throttling the timeouts: MinSchedulingDelay. Here mWindow.IsBackgroundInternal() check does not return correct values when the tab process is created via "open as new tab" and not switched to. The flow of method calls are as follows:

mWindow.IsBackgroundInternal() calls nsGlobalWindowInner::IsBackgroundInternal() which is set by nsGlobalWindowOuter::SetIsBackground that is called by
nsDocShell::ActivenessMaybeChanged() which is triggered by BrowsingContext::SetExplicitActive which is called by BrowsingContext::SetActive, and that's called by CanonicalBrowsingContext::RecomputeAppWindowVisibility().

RecomputeAppWindowVisibility method is triggered by OcclusionStateChanged event which Android does not fire at the moment. Firing this event will eventually fix the active/passive state for the tabs that are backgrounded, that will end up with throttling the timers at the correct place and time.

For the reference, here is the profiler for an unviewed tab ("open as a new tab" is clicked and the tab is not switched so unviewed.): https://share.firefox.dev/3wU4EWe
As seen in the profiler, setTimeout callbacks are triggered very frequently for a tab process which has not yet been visited/viewed. [Not included in profiler data: And even worse, when the app is taken to background, the callbacks are still triggered from the same tab process.]

The success metric: Currently when a tab is created via "open link in new tab" and not switched to, it consumes CPU though it is in the background. The value of CPU consumption changes from website to website, for some Pocket articles, Telegraph's news articles the value oscillates between 3%-8%. A test webpage is used for the comparison of values to define if the fix has improved the performance, i.e. lowered CPU consumption. The test page consumes 50% CPU and only makes setTimeout calls. After this fix, the expected behavior is to have the background tab process in idle state, i.e. ~0% CPU consumption.

Whiteboard: [geckoview:m111]
Whiteboard: [geckoview:m111] → [geckoview:m111] [geckoview:m112]
Whiteboard: [geckoview:m111] [geckoview:m112] → [geckoview:m111] [geckoview:m112] [fxdroid] [foundation] Juno
Whiteboard: [geckoview:m111] [geckoview:m112] [fxdroid] [foundation] Juno → [geckoview:m111] [geckoview:m112] [geckoview:m113] [fxdroid] [foundation] Juno

By means of setting the browser's initial activeness to false, a newly created background tab will
no longer have an active browsing context which reduces its cpu consumption while it is not selected.
The setTimeout callback is going to be throttled when the tab is created in the background by the
help of this fix.

Attachment #9324496 - Attachment description: WIP: Bug 1815015 - Set the browser's activeness to false by default at the time of creation. → Bug 1815015 - Set the browser's activeness to false by default at the time of creation.
Pushed by kkaya@mozilla.com:
https://hg.mozilla.org/integration/autoland/rev/e45c47334c6c
Set the browser's activeness to false by default at the time of creation. r=geckoview-reviewers,jonalmeida

There's a r+ patch which didn't land and no activity in this bug for 2 weeks.
:kaya, could you have a look please?
If you still have some work to do, you can add an action "Plan Changes" in Phabricator.
For more information, please visit auto_nag documentation.

Flags: needinfo?(kkaya)
Flags: needinfo?(jonalmeida942)

Clearing ni; kaya set the flag while he is investigating alternative solutions.

Flags: needinfo?(kkaya)
Flags: needinfo?(jonalmeida942)
Flags: needinfo?(kkaya)
Whiteboard: [geckoview:m111] [geckoview:m112] [geckoview:m113] [fxdroid] [foundation] Juno → [geckoview:m111] [geckoview:m112] [geckoview:m113] [geckoview:m114] [fxdroid] [foundation] Juno

The browser's activeness is set to false by default at the time of its creation. The reason is to let the background tabs have inactive browsers until they acquire a display to be visible to the user. This optimizes the cpu usage of unviewed tabs that are in the background.

Attachment #9324496 - Attachment is obsolete: true
Pushed by kkaya@mozilla.com:
https://hg.mozilla.org/integration/autoland/rev/02ae52790304
Set the activeness of the browser to false by default at the time of its creation. r=geckoview-reviewers,jonalmeida
Status: NEW → RESOLVED
Closed: 1 year ago
Resolution: --- → FIXED
Target Milestone: --- → 114 Branch

Setting status-firefox113=wontfix. I assume this change deserves more than one week of Beta test time before release, so we won't uplift this change to Beta 113.

I'm inclined to agree that this is a change which should have more bake time and thus shouldn't be considered for possible uplift to 113 down the road.

Regressions: 1836285
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Created:
Updated:
Size: