Bug 1453519 - Avoid process reselection inside RDM. r=ochameau, a=RyanVM
authorJ. Ryan Stinnett <jryans@gmail.com>
Fri, 13 Apr 2018 11:57:44 -0500
changeset 473243 6cfe31f3c435dfa53408db68b75d2f94a22fbef7
parent 473242 b2f564cbc97947e8a30a3ced7129f6ea008efe55
child 473244 c0a95808b3a3551b26d698d18e1d1c9db97bff4a
push id1728
push userjlund@mozilla.com
push dateMon, 18 Jun 2018 21:12:27 +0000
treeherdermozilla-release@c296fde26f5f [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersochameau, RyanVM
bugs1453519
milestone61.0
Bug 1453519 - Avoid process reselection inside RDM. r=ochameau, a=RyanVM Use `E10SUtils` to check for cases where browser code would try to force a browser to reselect a new process (such as when it is a preloaded browser) so that we can avoid any process changes once RDM is open. If such a case applies, navigate to about:blank first to trigger the process change before starting RDM. MozReview-Commit-ID: CxspLFXXotF
devtools/client/responsive.html/browser/swap.js
--- a/devtools/client/responsive.html/browser/swap.js
+++ b/devtools/client/responsive.html/browser/swap.js
@@ -1,15 +1,16 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 "use strict";
 
 const { Ci } = require("chrome");
+const { E10SUtils } = require("resource://gre/modules/E10SUtils.jsm");
 const { tunnelToInnerBrowser } = require("./tunnel");
 
 function debug(msg) {
   // console.log(`RDM swap: ${msg}`);
 }
 
 /**
  * Swap page content from an existing tab into a new browser within a container
@@ -84,19 +85,42 @@ function swapToInnerBrowser({ tab, conta
     let contentTabId = ourTab.linkedBrowser.frameLoader.tabParent.tabId;
     gBrowser._swapBrowserDocShells(ourTab, otherBrowser);
     if (otherBrowser.frameLoader.tabParent.tabId != contentTabId) {
       // Bug 1408602: Try to unwind to save tab content from being lost.
       throw new Error("Swapping tab content between browsers failed.");
     }
   };
 
+  // Wait for a browser to load into a new frame loader.
+  function loadURIWithNewFrameLoader(browser, uri, options) {
+    return new Promise(resolve => {
+      gBrowser.addEventListener("XULFrameLoaderCreated", resolve, { once: true });
+      browser.loadURI(uri, options);
+    });
+  }
+
   return {
 
     async start() {
+      // In some cases, such as a preloaded browser used for about:newtab, browser code
+      // will force a new frameloader on next navigation to ensure balanced process
+      // assignment.  If this case will happen here, navigate to about:blank first to get
+      // this out of way so that we stay within one process while RDM is open.
+      let { newFrameloader } = E10SUtils.shouldLoadURIInBrowser(
+        tab.linkedBrowser,
+        "about:blank"
+      );
+      if (newFrameloader) {
+        debug(`Tab will force a new frameloader on navigation, load about:blank first`);
+        await loadURIWithNewFrameLoader(tab.linkedBrowser, "about:blank", {
+          flags: Ci.nsIWebNavigation.LOAD_FLAGS_BYPASS_HISTORY,
+        });
+      }
+
       tab.isResponsiveDesignMode = true;
 
       // Hide the browser content temporarily while things move around to avoid displaying
       // strange intermediate states.
       tab.linkedBrowser.style.visibility = "hidden";
 
       // Freeze navigation temporarily to avoid "blinking" in the location bar.
       freezeNavigationState(tab);