Bug 1262946 - Don't focus the initial browser of a new window until it has painted. r?Gijs draft
authorMike Conley <mconley@mozilla.com>
Thu, 07 Apr 2016 11:42:17 -0400
changeset 348980 10bc9d81e54629d74a1e9530a057b8b646d48dfc
parent 348506 b6683e141c47c022598c0caac3ea8ba8c6236d42
child 348981 b670b11bc6f0c083487671f36a54675bd824f493
child 348984 95dd08bb3512351bcec43ec845e4793c8b005844
child 348991 c9e3478db083fe20e1b2996bc05d09f6812ed309
push id14980
push usermconley@mozilla.com
push dateFri, 08 Apr 2016 18:02:51 +0000
reviewersGijs
bugs1262946
milestone48.0a1
Bug 1262946 - Don't focus the initial browser of a new window until it has painted. r?Gijs This is in order to optimize the critical path (the presenting of content to the user). If we don't wait until the content has been presented for the tab switch, then we run the risk of causing the content to send sync IPC messages for IME up to the parent, which slows down the rendering of the content. MozReview-Commit-ID: B0anKV8YVUz
browser/base/content/browser.js
browser/base/content/tab-content.js
--- a/browser/base/content/browser.js
+++ b/browser/base/content/browser.js
@@ -1178,17 +1178,34 @@ var gBrowserInit = {
     Services.telemetry.getHistogramById("E10S_WINDOW").add(gMultiProcessBrowser);
 
     SidebarUI.startDelayedLoad();
 
     UpdateUrlbarSearchSplitterState();
 
     if (!(isBlankPageURL(uriToLoad) || uriToLoad == "about:privatebrowsing") ||
         !focusAndSelectUrlBar()) {
-      gBrowser.selectedBrowser.focus();
+      if (gBrowser.selectedBrowser.isRemoteBrowser) {
+        // If the initial browser is remote, in order to optimize for first paint,
+        // we'll defer switching focus to that browser until it has painted.
+        let focusedElement = document.commandDispatcher.focusedElement;
+        let mm = window.messageManager;
+        mm.addMessageListener("Browser:FirstPaint", function onFirstPaint() {
+          mm.removeMessageListener("Browser:FirstPaint", onFirstPaint);
+          // If focus didn't move while we were waiting for first paint, we're okay
+          // to move to the browser.
+          if (document.commandDispatcher.focusedElement == focusedElement) {
+            gBrowser.selectedBrowser.focus();
+          }
+        });
+      } else {
+        // If the initial browser is not remote, we can focus the browser
+        // immediately with no paint performance impact.
+        gBrowser.selectedBrowser.focus();
+      }
     }
 
     // Enable/Disable auto-hide tabbar
     gBrowser.tabContainer.updateVisibility();
 
     BookmarkingUI.init();
 
     gPrefService.addObserver(gHomeButton.prefDomain, gHomeButton, false);
--- a/browser/base/content/tab-content.js
+++ b/browser/base/content/tab-content.js
@@ -848,8 +848,13 @@ var RefreshBlocker = {
 
 RefreshBlocker.init();
 
 ExtensionContent.init(this);
 addEventListener("unload", () => {
   ExtensionContent.uninit(this);
   RefreshBlocker.uninit();
 });
+
+addEventListener("MozAfterPaint", function onFirstPaint() {
+  removeEventListener("MozAfterPaint", onFirstPaint);
+  sendAsyncMessage("Browser:FirstPaint");
+});