tabs.onUpdated: Update notification for tab load completion is ambiguous for discarded tabs
Categories
(WebExtensions :: General, defect, P3)
Tracking
(firefox81 affected, firefox82 affected, firefox83 affected)
People
(Reporter: julianhofstadter, Unassigned)
References
Details
Attachments
(2 files, 2 obsolete files)
status == "complete" update is sent 3 times when reloading a suspended tab, and it appears that the un-discarding/loading process is not complete until the 3rd time it is sent.
This can be demonstrated by the attached extension:
To use:
-
Create and open Firefox in new profile.
-
Install demo addon.
-
Close all tabs except 1.
-
Open 6 new additional tabs, and load with the following urls:
en.wikipedia.org/wiki/Train
en.wikipedia.org/wiki/Car
en.wikipedia.org/wiki/Bus
en.wikipedia.org/wiki/Ship
en.wikipedia.org/wiki/Bicycle
en.wikipedia.org/wiki/Motorcycle
(Wikipedia pages are good for this demonstration as their titles and urls are concise and similar.)
-
Click on the first tab (the non-Wikipedia tab) to make it the active one. (The active tab won't get suspended)
-
Click on the demo addon toolbar button (Green square with "test" in it.)
-
In browserAction popup click on the "suspend tabs" button
-
After a few seconds, in browserAction popup click on the "run script" button
-
Observe the tab throbbers indicating the suspended tabs are reloading in sequence one by one
-
After tabs finish reloading, observe the printout of results in the browserAction popup textarea. Several entries will appear for each tab showing the title at a given phase in the process.
Entries preceded by "get" contain titles retrieved from tabs.get(), each time the "complete" notification is sent.
(NOTE: Entries preceded by "update" can be ignored for this demo.)
One can see that "complete" gets sent 3 times for each tab. The fact that the retrieved title is:
tab url on the 1st "complete" occurrence
"New Tab" on the 2nd "complete" occurrence
back to tab url on the 3rd "complete" occurrence
seems to indicate that the full process of un-discarding the tab, then loading it, is not complete until the 3rd "complete" gets fired.
This leaves listeners a bit in the dark regarding whether when calling reload on a suspended tab, if the tab has completely finished reloading. It seems that for a listener to assume "complete" will get fired 3 times in order to determine the completion of loading is relying on an implementation detail that could change in the future.
It seems that when reloading suspended tabs, either
-
only a single "complete" notification should get sent after the tab is completely done with its process, or
-
if the intermediate "complete" notifications are needed somewhere for tracking the phases of the process, some other notification should be sent guaranteeing the finality of the process.
Comment 1•5 years ago
|
||
Hello,
I’ve managed to reproduce the issue based on the provided STR on the latest Nightly (83.0a1/20201006161706), Beta (82.0b8/20201006142214) and Release (81.0.1/20200930150533) under Windows 10 Pro 64-bit and Ubuntu 16.04 LTS.
The results output in the browserAction popup after running the script are the ones described in the report i.e. 3 occurrences of “complete” per tab.
Reporter | ||
Comment 2•5 years ago
|
||
Reporter | ||
Comment 3•5 years ago
|
||
It appears that the behavior for notifying that a discarded tab has finished loading is quite ambiguous. Behavior is different for:
Tab that has been opened in foreground with a url, then discarded using tabs.discard()
.
Tab that was opened in discarded state using tabs.create({ url, windowId, discarded: true })
.
Tab that was opened in discarded state using session restore.
The difference in behavior includes the number of "complete"
updates which get sent.
Another demo addon has been uploaded which better demonstrates the various behavior:
- Create new profile
- In Preferences ensure "Startup" > "Restore previous session" is checked
- Install the demo addon https://bugzilla.mozilla.org/attachment.cgi?id=9180588
- Remove all but one tab
- Open new tab and go to https://en.wikipedia.org/wiki/Car
- Make the first tab active (non-Wikipedia one)
- Open demo addon browserAction popup by clicking on green "Test" toolbar button. Be sure popup doesn't close during test
- Ensure the first tab in each window is the active one
- Click "discard tabs" (This calls
tabs.discard()
on every tab except active ones.) - After a few seconds, click "reload tabs"
- After a few seconds, results will be printed in the textarea
- Copy text before popup closes and record in a safe place
- Observe in results
"complete"
was sent 3 times on the (discarded)en.wikipedia.org/wiki/Car
tab - Observe evolution of title
- Observe title in the Wikipedia tabs is now the url
start reload: tabId: 8 ts: 1602195077474 discarded: true
title: tabId: 8 ts: 1602195077573 title: en.wikipedia.org/wiki/Car
complete: tabId: 8 ts: 1602195077574 times: 1
title: tabId: 8 ts: 1602195077576 title: Car - Wikipedia
title: tabId: 8 ts: 1602195077579 title: New Tab
complete: tabId: 8 ts: 1602195077580 times: 2
title: tabId: 8 ts: 1602195077804 title: en.wikipedia.org/wiki/Car
complete: tabId: 8 ts: 1602195078824 times: 3
executed on 3th "complete"
=======================================
- If browserAction popup is closed, reopen
- Click "reload tabs" so correct titles are again showing
- Ensure the first tab in each window is the active one
- Click "discard tabs"
- Click "open window"
- browserAction popup will close and a new window will open with 2 tabs. The first tab is active, the second tab was opened in a discarded state using
tabs.create({ url, windowId, discarded: true })
. Its title will be the url. - Open browserAction popup, keep open
- Click "reload tabs"
- Copy text before popup closes and record in a safe place
- Observe (discarded)
en.wikipedia.org/wiki/Car
tab again sent 3"complete"
updates - Observe (discarded)
en.wikipedia.org/wiki/Cattle
tab sent 4"complete"
updates - Observe evolution of title for each
- Observe title in the Wikipedia tabs is now the url
start reload: tabId: 8 ts: 1602195781187 discarded: true
title: tabId: 8 ts: 1602195781240 title: en.wikipedia.org/wiki/Car
complete: tabId: 8 ts: 1602195781242 times: 1
title: tabId: 8 ts: 1602195781296 title: Car - Wikipedia
title: tabId: 8 ts: 1602195781300 title: New Tab
complete: tabId: 8 ts: 1602195781301 times: 2
title: tabId: 8 ts: 1602195781549 title: en.wikipedia.org/wiki/Car
complete: tabId: 8 ts: 1602195782399 times: 3
executed on 3th "complete"
=======================================
start reload: tabId: 10 ts: 1602195782569 discarded: true
complete: tabId: 10 ts: 1602195782615 times: 1
complete: tabId: 10 ts: 1602195782620 times: 2
title: tabId: 10 ts: 1602195782641 title: New Tab
complete: tabId: 10 ts: 1602195782644 times: 3
title: tabId: 10 ts: 1602195783064 title: en.wikipedia.org/wiki/Cattle
complete: tabId: 10 ts: 1602195785372 times: 4
executed on 4th "complete"
=======================================
- If browserAction popup is closed, reopen
- Click "reload tabs" so correct titles are showing in the discarded tabs
- Ensure the first tab in each window is the active one
- Click "discard tabs"
- After a few seconds, click "reload tabs"
- Copy text before popup closes and record in a safe place
- Observe, like before (discarded)
en.wikipedia.org/wiki/Car
tab again sent 3"complete"
updates - Observe, like before (discarded)
en.wikipedia.org/wiki/Cattle
tab sent 4"complete"
updates - Observe evolution of title for each is like before
- Observe that although we discarded tabs using
tabs.discard()
, the tabs still retained the characteristics which caused them to send either 3 or 4"complete"
updates previously. - Observe title in the Wikipedia tabs is now the url
start reload: tabId: 5 ts: 1602196929738 discarded: true
title: tabId: 5 ts: 1602196929826 title: en.wikipedia.org/wiki/Car
complete: tabId: 5 ts: 1602196929828 times: 1
title: tabId: 5 ts: 1602196929835 title: Car - Wikipedia
title: tabId: 5 ts: 1602196929844 title: New Tab
complete: tabId: 5 ts: 1602196929844 times: 2
title: tabId: 5 ts: 1602196929914 title: en.wikipedia.org/wiki/Car
complete: tabId: 5 ts: 1602196930938 times: 3
executed on 3th "complete"
=======================================
start reload: tabId: 7 ts: 1602196931103 discarded: true
complete: tabId: 7 ts: 1602196931149 times: 1
title: tabId: 7 ts: 1602196931151 title: en.wikipedia.org/wiki/Cattle
complete: tabId: 7 ts: 1602196931154 times: 2
title: tabId: 7 ts: 1602196931166 title: Cattle - Wikipedia
title: tabId: 7 ts: 1602196931167 title: New Tab
complete: tabId: 7 ts: 1602196931169 times: 3
title: tabId: 7 ts: 1602196931198 title: en.wikipedia.org/wiki/Cattle
complete: tabId: 7 ts: 1602196932331 times: 4
executed on 4th "complete"
=======================================
- If browserAction popup is closed, reopen
- Click "reload tabs" so correct titles are showing in the discarded tabs
- Ensure the first tab in each window is the active one
- Restart Firefox (having ensured that tabs will be restored)
- Open browserAction popup, keep open
- Click "reload tabs"
- Copy text before popup closes and record in a safe place
- Observe that now all suspended tabs send 4
"complete"
updates - Observe that now with all suspended tabs, there are no
"title"
updates - Observe that now that none of the titles were corrupted in the tabs
start reload: tabId: 3 ts: 1602197275721 discarded: true
complete: tabId: 3 ts: 1602197275813 times: 1
complete: tabId: 3 ts: 1602197275816 times: 2
complete: tabId: 3 ts: 1602197275823 times: 3
complete: tabId: 3 ts: 1602197277170 times: 4
executed on 4th "complete"
=======================================
start reload: tabId: 4 ts: 1602197277354 discarded: true
complete: tabId: 4 ts: 1602197277388 times: 1
complete: tabId: 4 ts: 1602197277391 times: 2
complete: tabId: 4 ts: 1602197277396 times: 3
complete: tabId: 4 ts: 1602197278369 times: 4
executed on 4th "complete"
=======================================
- Ensure the first tab in each window is the active one
- If browserAction popup is closed, reopen
- Click "discard tabs"
- After a few seconds, click "reload tabs"
- Copy text before popup closes and record in a safe place
- Observe again that all suspended tabs send 4
"complete"
updates - Observe again that with all suspended tabs, there are no
"title"
updates - Observe again that that none of the titles were corrupted in the tabs
start reload: tabId: 3 ts: 1602198152737 discarded: true
complete: tabId: 3 ts: 1602198152873 times: 1
complete: tabId: 3 ts: 1602198152875 times: 2
complete: tabId: 3 ts: 1602198152894 times: 3
complete: tabId: 3 ts: 1602198154383 times: 4
executed on 4th "complete"
=======================================
start reload: tabId: 4 ts: 1602198154743 discarded: true
complete: tabId: 4 ts: 1602198154782 times: 1
complete: tabId: 4 ts: 1602198154782 times: 2
complete: tabId: 4 ts: 1602198154789 times: 3
complete: tabId: 4 ts: 1602198156051 times: 4
executed on 4th "complete"
=======================================
Reporter | ||
Updated•5 years ago
|
Reporter | ||
Comment 4•5 years ago
|
||
Reporter | ||
Comment 5•5 years ago
|
||
So sorry, I uploaded the wrong file for comment 2 and comment 3.
This is the correct one: https://bugzilla.mozilla.org/attachment.cgi?id=9180594
Comment 6•5 years ago
|
||
Is this a recent regression, or has it always worked like this?
Comment 7•5 years ago
|
||
Hello,
I’ve attempted a bisection, running a check from 2018-01-01 up until the present day.
Builds up to and including April 2018 behave as described in the report, however, from March 2018 and earlier, the provided extension does not return any results (it gets stuck at “Reloading...” in the pop-up).
Based on the current results, the issue might not be a recent regression since this behavior was exhibited since early 2018.
Reporter | ||
Comment 8•5 years ago
|
||
(In reply to Alex Cornestean from comment #7)
Hello,
I’ve attempted a bisection, running a check from 2018-01-01 up until the present day.
Builds up to and including April 2018 behave as described in the report, however, from March 2018 and earlier, the provided extension does not return any results (it gets stuck at “Reloading...” in the pop-up).
Based on the current results, the issue might not be a recent regression since this behavior was exhibited since early 2018.
On 59.0 (March 2018) I get the following errors:
JavaScript error: moz-extension://802dc965-d3f3-5e4e-9635-49dfe73883d9/background/background.js, line 19: Error: Type error for parameter createProperties (Unexpected property "discarded") for tabs.create.
JavaScript error: moz-extension://802dc965-d3f3-5e4e-9635-49dfe73883d9/browserAction/browserAction.js, line 30: Error: Incorrect argument types for tabs.onUpdated.
Some of the options were not implemented yet, so the demo addon won't work for those earlier versions. (Maybe tab discarding wasn't implemented yet?)
Comment 9•5 years ago
|
||
Hi Julian,
What is the url property in the tab events received while reproducing this issue? would you mind to double-check that and let us know?
Comment 10•5 years ago
|
||
This is not the only case where multiple status change notifications are being sent, bug 1635328 is another one.
This issue, of knowing whether the tab is in some "ready" / "final" state, has come up multiple times in the past. The tabs
API tries to account for several of them when the tab is created by the tabs.create
and tabs.duplicate
API, but doesn't account for (un)discarding tabs. I am hesitant to increasing the complexity of the implementation, especially because the behavior is subtle and prone to bugs.
only a single "complete" notification should get sent after the tab is completely done with its process, or
This is probably not feasible. It means that we have to somehow suppress notifications from content. But at the same time, extensions are already able to observe the presence of the page (e.g. through content scripts), which may result in a mismatch in actual state and reported/known state.
if the intermediate "complete" notifications are needed somewhere for tracking the phases of the process, some other notification should be sent guaranteeing the finality of the process.
That desire looks reasonable from the point of view of an extension that needs the information, but it does make the API surface more complicated for extensions that observe onUpdated
events without filter.
Comment 11•5 years ago
|
||
To check if only the last event contains the url on restoring discarded tabs.
Comment 12•5 years ago
|
||
Bugbug thinks this bug should belong to this component, but please revert this change in case of error.
Updated•5 years ago
|
Reporter | ||
Comment 13•5 years ago
|
||
(In reply to Luca Greco [:rpl] [:luca] [:lgreco] from comment #9)
Hi Julian,
What is the url property in the tab events received while reproducing this issue? would you mind to double-check that and let us know?
Here is the output showing URLs.
Output calling reload()
on tabs which were loaded then discarded by calling tabs.discard()
:
=======================================
start reload: tabId: 7 ts: 1606393455658 discarded: true
title: tabId: 7 ts: 1606393455676 title: Car - Wikipedia
complete: tabId: 7 ts: 1606393455688 count: 1
title: tabId: 7 ts: 1606393455689 title: en.wikipedia.org/wiki/Car
complete: tabId: 7 ts: 1606393455694 count: 2
url: tabId: 7 ts: 1606393455694 url: https://en.wikipedia.org/wiki/Car
title: tabId: 7 ts: 1606393455707 title: Car - Wikipedia
title: tabId: 7 ts: 1606393455715 title: New Tab
complete: tabId: 7 ts: 1606393455718 count: 3
url: tabId: 7 ts: 1606393455718 url: about:blank
title: tabId: 7 ts: 1606393455787 title: en.wikipedia.org/wiki/Car
url: tabId: 7 ts: 1606393455795 url: https://en.wikipedia.org/wiki/Car
complete: tabId: 7 ts: 1606393456461 count: 4
executed on 4th "complete"
=======================================
start reload: tabId: 8 ts: 1606393456461 discarded: true
title: tabId: 8 ts: 1606393456480 title: Transport - Wikipedia
complete: tabId: 8 ts: 1606393456516 count: 1
title: tabId: 8 ts: 1606393456518 title: en.wikipedia.org/wiki/Transport
complete: tabId: 8 ts: 1606393456519 count: 2
url: tabId: 8 ts: 1606393456519 url: https://en.wikipedia.org/wiki/Transport
title: tabId: 8 ts: 1606393456525 title: Transport - Wikipedia
title: tabId: 8 ts: 1606393456529 title: New Tab
complete: tabId: 8 ts: 1606393456534 count: 3
url: tabId: 8 ts: 1606393456534 url: about:blank
title: tabId: 8 ts: 1606393456595 title: en.wikipedia.org/wiki/Transport
url: tabId: 8 ts: 1606393456598 url: https://en.wikipedia.org/wiki/Transport
complete: tabId: 8 ts: 1606393457142 count: 4
executed on 4th "complete"
=======================================
start reload: tabId: 9 ts: 1606393457142 discarded: true
title: tabId: 9 ts: 1606393457165 title: Developed country - Wikipedia
complete: tabId: 9 ts: 1606393457188 count: 1
title: tabId: 9 ts: 1606393457190 title: en.wikipedia.org/wiki/Developed_country
complete: tabId: 9 ts: 1606393457192 count: 2
url: tabId: 9 ts: 1606393457192 url: https://en.wikipedia.org/wiki/Developed_country
title: tabId: 9 ts: 1606393457199 title: Developed country - Wikipedia
title: tabId: 9 ts: 1606393457210 title: New Tab
complete: tabId: 9 ts: 1606393457216 count: 3
url: tabId: 9 ts: 1606393457216 url: about:blank
title: tabId: 9 ts: 1606393457280 title: en.wikipedia.org/wiki/Developed_country
url: tabId: 9 ts: 1606393457289 url: https://en.wikipedia.org/wiki/Developed_country
complete: tabId: 9 ts: 1606393457986 count: 4
executed on 4th "complete"
=======================================
Output calling reload on discarded tabs after fresh restart:
=======================================
start reload: tabId: 3 ts: 1606393689871 discarded: true
complete: tabId: 3 ts: 1606393689908 count: 1
complete: tabId: 3 ts: 1606393689911 count: 2
url: tabId: 3 ts: 1606393689911 url: https://en.wikipedia.org/wiki/Car
complete: tabId: 3 ts: 1606393689919 count: 3
url: tabId: 3 ts: 1606393689919 url: about:blank
url: tabId: 3 ts: 1606393690238 url: https://en.wikipedia.org/wiki/Car
complete: tabId: 3 ts: 1606393690818 count: 4
executed on 4th "complete"
=======================================
start reload: tabId: 4 ts: 1606393690818 discarded: true
complete: tabId: 4 ts: 1606393690846 count: 1
complete: tabId: 4 ts: 1606393690847 count: 2
url: tabId: 4 ts: 1606393690847 url: https://en.wikipedia.org/wiki/Transport
complete: tabId: 4 ts: 1606393690859 count: 3
url: tabId: 4 ts: 1606393690859 url: about:blank
url: tabId: 4 ts: 1606393690891 url: https://en.wikipedia.org/wiki/Transport
complete: tabId: 4 ts: 1606393691386 count: 4
executed on 4th "complete"
=======================================
start reload: tabId: 5 ts: 1606393691386 discarded: true
complete: tabId: 5 ts: 1606393691414 count: 1
complete: tabId: 5 ts: 1606393691415 count: 2
url: tabId: 5 ts: 1606393691415 url: https://en.wikipedia.org/wiki/Developed_country
complete: tabId: 5 ts: 1606393691419 count: 3
url: tabId: 5 ts: 1606393691419 url: about:blank
url: tabId: 5 ts: 1606393691450 url: https://en.wikipedia.org/wiki/Developed_country
complete: tabId: 5 ts: 1606393692174 count: 4
executed on 4th "complete"
=======================================
Reporter | ||
Comment 14•5 years ago
|
||
Demo addon version 0.0.3 also displays url updates.
Comment 15•5 years ago
|
||
I did spent some time looking if any of the details we currently send as part of the tabs.onUpdated event could already be used by the extensions to identify which of the tab.onUpdated events represent the actual final loading related to a tab being undiscarded,
but I think that I can confirm that at the moment none of them is enough to let the extension determine which will be the final load, as the reported was also stating.
By taking a more deeper look into the properties and DOM attributes on the native tab in Firefox Desktop builds, I did notice that
the native tab does have the pending
attribute set until the tab is completely restored, and at that point the pending
attribute is being removed from the restored tab.
At the moment the our discarded
attribute getter is only checking if the nativeTab does have a linked panel:
get discarded() {
return !this.nativeTab.linkedPanel;
}
And so, while filtering out all the tabs.onUpdated events emitted between starting to restore a tab and when the tab is completely restored may not be really that practical, one reasonable way to let the extension to better assess on its own which is the final onUpdate "complete" event may be to make the discarded
getter to also check if the pending
attribute it still set, e.g. something like:
get discarded() {
// return discarded true if the nativeTab doesn't have a linked panel (is still fully discarded) or if it does still have the pending attribute
// (is fully discarded or in the process of being restored).
return !this.nativeTab.linkedPanel || this.nativeTab.hasAttribute("pending");
}
Comment 16•5 years ago
•
|
||
We should make sure that the onUpdated event for the "discarded" filter is correct. From what I understand in comment 15, listening for the discarded event will result in tab.discared == false during the TabBrowserInserted event. If that is indeed the case, we should instead listen for the "pending" attribute using "TabAttrModified".
onUpdated with a discarded filter should fire when a tab is fully discarded or fully restored.
It seems we only have tests that watch for a tab being discarded, but not a test for when a tab is restored. I don't see any test that uses and tests the discarded filter.
[1] https://searchfox.org/mozilla-central/rev/23c25cd32a1e87095301273937b4ee162f41e860/browser/components/extensions/test/browser/browser_ext_tabs_discard.js#55
[2] https://searchfox.org/mozilla-central/rev/23c25cd32a1e87095301273937b4ee162f41e860/browser/components/extensions/test/browser/browser_ext_tabs_discarded.js#79
[3] https://searchfox.org/mozilla-central/rev/23c25cd32a1e87095301273937b4ee162f41e860/browser/components/extensions/test/browser/browser_ext_tabs_onUpdated_filter.js#295
Updated•4 years ago
|
Description
•