Bug 1256472 - When restoring a window, initialize each browser tab as remote if possible. r=mikedeboer

Originally, we were forcing these restored background tabs to be non-remote by default.
This was because we didn't want them to show the crashed tab favicon nor show about:tabcrashed
if the user hadn't restored them before.

Bug 1241459 added infrastructure that makes it possible to put crashed background tabs into
the "restore on demand" state again, without showing about:tabcrashed or showing the crashed
tab favicon.

This means we should be able to restore tabs in the content process again which should take
some load off of the parent process during session restore, which is good for perceived
performance.

Note that if the content process does crash, the background tabs are then loaded in the parent
process. Restoring them on demand will then do the remoteness flip.

MozReview-Commit-ID: 1mWe0td6geB

--HG--
extra : rebase_source : 5e1dbbaf0e1fb641bd43f821980ab5dff7272b04
This commit is contained in:
Mike Conley 2017-03-14 10:01:38 -04:00
parent 9ce53ecd28
commit a04621c4a8
2 changed files with 43 additions and 75 deletions

View File

@ -3220,14 +3220,9 @@ var SessionStoreInternal = {
let userContextId = winData.tabs[t].userContextId;
let reuseExisting = t < openTabCount &&
(tabbrowser.tabs[t].getAttribute("usercontextid") == (userContextId || ""));
// If the tab is pinned, then we'll be loading it right away, and
// there's no need to cause a remoteness flip by loading it initially
// non-remote.
let forceNotRemote = !winData.tabs[t].pinned;
let tab = reuseExisting ? tabbrowser.tabs[t] :
tabbrowser.addTab("about:blank",
let tab = reuseExisting ? this._maybeUpdateBrowserRemoteness(tabbrowser.tabs[t])
: tabbrowser.addTab("about:blank",
{skipAnimation: true,
forceNotRemote,
userContextId});
// If we inserted a new tab because the userContextId didn't match with the
@ -3495,9 +3490,6 @@ var SessionStoreInternal = {
TabRestoreQueue.add(tab);
}
this._maybeUpdateBrowserRemoteness({ tabbrowser, tab,
willRestoreImmediately });
// Increase the busy state counter before modifying the tab.
this._setWindowStateBusy(window);
@ -3937,46 +3929,21 @@ var SessionStoreInternal = {
* Determines whether or not a tab that is being restored needs
* to have its remoteness flipped first.
*
* @param (object) with the following properties:
*
* tabbrowser (<xul:tabbrowser>):
* The tabbrowser that the browser belongs to.
*
* tab (<xul:tab>):
* The tab being restored
*
* willRestoreImmediately (bool):
* true if the tab is going to have its content
* restored immediately by the caller.
* @param tab (<xul:tab>):
* The tab being restored.
*
* @returns tab (<xul:tab>)
* The tab that was passed.
*/
_maybeUpdateBrowserRemoteness({ tabbrowser, tab,
willRestoreImmediately }) {
// If the browser we're attempting to restore happens to be
// remote, we need to flip it back to non-remote if it's going
// to go into the pending background tab state. This is to make
// sure that a background tab can't crash if it hasn't yet
// been restored.
//
// Normally, when a window is restored, the tabs that SessionStore
// inserts are non-remote - but the initial browser is, by default,
// remote, so this check and flip covers this case. The other case
// is when window state is overwriting the state of an existing
// window with some remote tabs.
_maybeUpdateBrowserRemoteness(tab) {
let win = tab.ownerGlobal;
let tabbrowser = win.gBrowser;
let browser = tab.linkedBrowser;
// There are two ways that a tab might start restoring its content
// very soon - either the caller is going to restore the content
// immediately, or the TabRestoreQueue is set up so that the tab
// content is going to be restored in the very near future. In
// either case, we don't want to flip remoteness, since the browser
// will soon be loading content.
let willRestore = willRestoreImmediately ||
TabRestoreQueue.willRestoreSoon(tab);
if (browser.isRemoteBrowser && !willRestore) {
tabbrowser.updateBrowserRemoteness(browser, false);
if (win.gMultiProcessBrowser && !browser.isRemoteBrowser) {
tabbrowser.updateBrowserRemoteness(browser, true);
}
return tab;
},
/**

View File

@ -104,7 +104,8 @@ const PINNED_STATE = {
*
*/
function* runScenarios(scenarios) {
for (let scenario of scenarios) {
for (let [scenarioIndex, scenario] of scenarios.entries()) {
info("Running scenario " + scenarioIndex);
// Let's make sure our scenario is sane first.
Assert.equal(scenario.expectedFlips.length,
scenario.expectedRemoteness.length,
@ -234,10 +235,11 @@ add_task(function*() {
selectedTab: 3,
// The initial tab is remote and should go into
// the background state. The second and third tabs
// are new and should be initialized non-remote.
expectedFlips: [true, false, true],
// Only the selected tab should be remote.
expectedRemoteness: [false, false, true],
// are new and should initialize remotely as well.
// There should therefore be no remoteness flips.
expectedFlips: [false, false, false],
// All tabs should now be remote.
expectedRemoteness: [true, true, true],
},
// A single remote tab, and this is the one that's going
@ -249,10 +251,10 @@ add_task(function*() {
selectedTab: 1,
// The initial tab is remote and selected, so it should
// not flip remoteness. The other two new tabs should
// be non-remote by default.
// initialize as remote unrestored background tabs.
expectedFlips: [false, false, false],
// Only the selected tab should be remote.
expectedRemoteness: [true, false, false],
// All tabs should now be remote.
expectedRemoteness: [true, true, true],
},
// A single remote tab which starts selected. We set the
@ -265,10 +267,10 @@ add_task(function*() {
selectedTab: 0,
// The initial tab is remote and selected, so it should
// not flip remoteness. The other two new tabs should
// be non-remote by default.
// initialize as remote unrestored background tabs.
expectedFlips: [false, false, false],
// Only the selected tab should be remote.
expectedRemoteness: [true, false, false],
// All tabs should now be remote.
expectedRemoteness: [true, true, true],
},
// An initially remote tab, but we're going to load
@ -283,8 +285,8 @@ add_task(function*() {
// so it should stay remote. The second tab is new
// and pinned, so it should start remote and not flip.
// The third tab is not pinned, but it is selected,
// so it will start non-remote, and then flip remoteness.
expectedFlips: [false, false, true],
// so it will start remote.
expectedFlips: [false, false, false],
// Both pinned tabs and the selected tabs should all
// end up being remote.
expectedRemoteness: [true, true, true],
@ -296,12 +298,12 @@ add_task(function*() {
initialSelectedTab: 1,
stateToRestore: SIMPLE_STATE,
selectedTab: 2,
// The initial tab is non-remote and should stay
// that way. The second and third tabs are new and
// should be initialized non-remote.
expectedFlips: [false, true, false],
// Only the selected tab should be remote.
expectedRemoteness: [false, true, false],
// The initial tab is non-remote and should become remote.
// The second and third tabs are new and should be initialized
// as remote.
expectedFlips: [true, false, false],
// All tabs should now be remote.
expectedRemoteness: [true, true, true],
},
// A mixture of remote and non-remote tabs.
@ -310,12 +312,12 @@ add_task(function*() {
initialSelectedTab: 1,
stateToRestore: SIMPLE_STATE,
selectedTab: 3,
// The initial tab is remote and should flip to non-remote
// as it is put into the background. The second tab should
// stay non-remote, and the third one should stay remote.
expectedFlips: [true, false, false],
// Only the selected tab should be remote.
expectedRemoteness: [false, false, true],
// The initial tab is remote and should stay that way, even
// when put into the background. The second tab should flip
// remoteness, and the third one should stay remote.
expectedFlips: [false, true, false],
// All tabs should now be remote.
expectedRemoteness: [true, true, true],
},
// An initially non-remote tab, but we're going to load
@ -330,10 +332,9 @@ add_task(function*() {
// so it should flip remoteness. The second tab is new
// and pinned, so it should start remote and not flip.
// The third tab is not pinned, but it is selected,
// so it will start non-remote, and then flip remoteness.
expectedFlips: [true, false, true],
// Both pinned tabs and the selected tabs should all
// end up being remote.
// so it will start remote, and not flip remoteness.
expectedFlips: [true, false, false],
// All tabs should now be remote.
expectedRemoteness: [true, true, true],
},
];