Bug: unloadNonRequiredTabs/this.unloadTimer<[AsyncTabSwitcher.sys.mjs]:JS fires every 300ms
Status: NEW
Priority: P3
Created: 2024-06-06 11:30:10+00:00
Resolved: 2024-06-19 12:33:29+00:00

In the profile (https://share.firefox.dev/3Vrt6LR) of an unrelated bug report (bug 1849393), Florian noticed that my profile frequently dispatches an `unloadNonRequiredTabs` call with a 300ms frequency (https://bugzilla.mozilla.org/show_bug.cgi?id=1849393#c52).

Upon attaching the Browser Toolbox, I can see that this code is hit: https://searchfox.org/mozilla-central/rev/fa86401b80f19afb6ed9bfca127ecc5e3a6f0cdc/browser/components/tabbrowser/AsyncTabSwitcher.sys.mjs#724,752,756-761

`numPending` is 1 because there is a `tab` with `state` 3 (STATE_UNLOADING).
I recognized that tab as a tab that was discarded (due to it being inactive at the time of session restore at startup), and after I accidentally focused it (several days into an active Firefox session with several windows), I switched back to the original tab and used ["Discard Tab" context menu from the Discard Tab add-on](https://addons.mozilla.org/en-US/firefox/addon/discard-tab/), which internally calls [`gBrowser.discardBrowser(nativeTab)`](https://searchfox.org/mozilla-central/rev/fa86401b80f19afb6ed9bfca127ecc5e3a6f0cdc/browser/components/extensions/parent/ext-tabs.js#863-865). Also noteworthy is that the tab that I discarded was a very large Google Doc, and upon doing so I saw the "Given tab is not restoring" error in the global Browser Console, from https://searchfox.org/mozilla-central/rev/fa86401b80f19afb6ed9bfca127ecc5e3a6f0cdc/browser/components/sessionstore/SessionStore.sys.mjs#6647

With the Browser Console, I can confirm that `gBrowser._switcher.tabState.get(gBrowser.browsers[0])` is 3 (aka STATE_UNLOADING) despite the tab supposedly having been discarded (so it should be STATE_UNLOADED?). Not sure if this is a separate bug, but I find it quite a coincidence, especially because this state is part of the condition that determines whether the timer should be scheduled.

The other part of the condition is `tab !== this.requestedTab`. I can confirm that this condition is also true, because `requestedTab` is the tab I switched to and is currently the active tab in the window.

I tried recreating the error in a completely new profile. I was able to trigger the "Given tab is not restoring" error, as follows:
1. Open https://html.spec.whatwg.org/ (a large HTML page).
2. Install https://addons.mozilla.org/en-US/firefox/addon/discard-tab/
3. Quit Firefox
4. Start Firefox, it will open with the HTML spec tab (step 1) inactive and the add-ons page (step 2) focused.
5. Click on tab 1, quickly click on tab 2, then right-click on tab 1 and choose "Discard Tab".
6. The global browser console will show "Given tab is not restoring"

I can however not check whether this bug (i.e. the repeated timer) can be triggered through that, because `gBrowser._switcher` is null.

Version: Firefox 128.0a1, build ID 20240528001238 on macOS. Not sure if related, but Firefox Nightly parent process has been using a full CPU core, and this has already been ongoing for days. The original profile was shared at https://bugzilla.mozilla.org/show_bug.cgi?id=1849393#c51, the profile shared above is just a zoomed in version of it.